blockd.h 23.3 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
2
3
4
5
6
7
8
9
10
/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

11
12
#ifndef VP10_COMMON_BLOCKD_H_
#define VP10_COMMON_BLOCKD_H_
Jingning Han's avatar
Jingning Han committed
13
14
15

#include "./vpx_config.h"

16
#include "vpx_dsp/vpx_dsp_common.h"
Jingning Han's avatar
Jingning Han committed
17
18
19
#include "vpx_ports/mem.h"
#include "vpx_scale/yv12config.h"

20
#include "vp10/common/common_data.h"
21
#include "vp10/common/quant_common.h"
22
23
24
25
26
27
#include "vp10/common/entropy.h"
#include "vp10/common/entropymode.h"
#include "vp10/common/mv.h"
#include "vp10/common/scale.h"
#include "vp10/common/seg_common.h"
#include "vp10/common/tile_common.h"
Jingning Han's avatar
Jingning Han committed
28
29
30
31
32
33
34
35
36
37
38
39
40

#ifdef __cplusplus
extern "C" {
#endif

#define MAX_MB_PLANE 3

typedef enum {
  KEY_FRAME = 0,
  INTER_FRAME = 1,
  FRAME_TYPES,
} FRAME_TYPE;

41
#if CONFIG_EXT_INTERP && SUPPORT_NONINTERPOLATING_FILTERS
clang-format's avatar
clang-format committed
42
#define IsInterpolatingFilter(filter) (vp10_is_interpolating_filter(filter))
43
#else
clang-format's avatar
clang-format committed
44
#define IsInterpolatingFilter(filter) (1)
45
46
#endif  // CONFIG_EXT_INTERP && SUPPORT_NONINTERPOLATING_FILTERS

Jingning Han's avatar
Jingning Han committed
47
static INLINE int is_inter_mode(PREDICTION_MODE mode) {
Yue Chen's avatar
Yue Chen committed
48
#if CONFIG_EXT_INTER
49
  return mode >= NEARESTMV && mode <= NEW_NEWMV;
Yue Chen's avatar
Yue Chen committed
50
#else
Jingning Han's avatar
Jingning Han committed
51
  return mode >= NEARESTMV && mode <= NEWMV;
Yue Chen's avatar
Yue Chen committed
52
53
54
55
#endif  // CONFIG_EXT_INTER
}

#if CONFIG_EXT_INTER
56
57
58
59
60
61
62
63
static INLINE int is_inter_singleref_mode(PREDICTION_MODE mode) {
  return mode >= NEARESTMV && mode <= NEWFROMNEARMV;
}

static INLINE int is_inter_compound_mode(PREDICTION_MODE mode) {
  return mode >= NEAREST_NEARESTMV && mode <= NEW_NEWMV;
}

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
static INLINE PREDICTION_MODE compound_ref0_mode(PREDICTION_MODE mode) {
  static PREDICTION_MODE lut[MB_MODE_COUNT] = {
    MB_MODE_COUNT,  // DC_PRED            0
    MB_MODE_COUNT,  // V_PRED             1
    MB_MODE_COUNT,  // H_PRED             2
    MB_MODE_COUNT,  // D45_PRED           3
    MB_MODE_COUNT,  // D135_PRED          4
    MB_MODE_COUNT,  // D117_PRED          5
    MB_MODE_COUNT,  // D153_PRED          6
    MB_MODE_COUNT,  // D207_PRED          7
    MB_MODE_COUNT,  // D63_PRED           8
    MB_MODE_COUNT,  // TM_PRED            9
    MB_MODE_COUNT,  // NEARESTMV         10
    MB_MODE_COUNT,  // NEARMV            11
    MB_MODE_COUNT,  // ZEROMV            12
    MB_MODE_COUNT,  // NEWMV             13
    MB_MODE_COUNT,  // NEWFROMNEARMV     14
    NEARESTMV,      // NEAREST_NEARESTMV 15
    NEARESTMV,      // NEAREST_NEARMV    16
    NEARMV,         // NEAR_NEARESTMV    17
    NEARMV,         // NEAR_NEARMV       18
    NEARESTMV,      // NEAREST_NEWMV     19
    NEWMV,          // NEW_NEARESTMV     20
    NEARMV,         // NEAR_NEWMV        21
    NEWMV,          // NEW_NEARMV        22
    ZEROMV,         // ZERO_ZEROMV       23
    NEWMV,          // NEW_NEWMV         24
  };
  assert(is_inter_compound_mode(mode));
  return lut[mode];
}

static INLINE PREDICTION_MODE compound_ref1_mode(PREDICTION_MODE mode) {
  static PREDICTION_MODE lut[MB_MODE_COUNT] = {
    MB_MODE_COUNT,  // DC_PRED            0
    MB_MODE_COUNT,  // V_PRED             1
    MB_MODE_COUNT,  // H_PRED             2
    MB_MODE_COUNT,  // D45_PRED           3
    MB_MODE_COUNT,  // D135_PRED          4
    MB_MODE_COUNT,  // D117_PRED          5
    MB_MODE_COUNT,  // D153_PRED          6
    MB_MODE_COUNT,  // D207_PRED          7
    MB_MODE_COUNT,  // D63_PRED           8
    MB_MODE_COUNT,  // TM_PRED            9
    MB_MODE_COUNT,  // NEARESTMV         10
    MB_MODE_COUNT,  // NEARMV            11
    MB_MODE_COUNT,  // ZEROMV            12
    MB_MODE_COUNT,  // NEWMV             13
    MB_MODE_COUNT,  // NEWFROMNEARMV     14
    NEARESTMV,      // NEAREST_NEARESTMV 15
    NEARMV,         // NEAREST_NEARMV    16
    NEARESTMV,      // NEAR_NEARESTMV    17
    NEARMV,         // NEAR_NEARMV       18
    NEWMV,          // NEAREST_NEWMV     19
    NEARESTMV,      // NEW_NEARESTMV     20
    NEWMV,          // NEAR_NEWMV        21
    NEARMV,         // NEW_NEARMV        22
    ZEROMV,         // ZERO_ZEROMV       23
    NEWMV,          // NEW_NEWMV         24
  };
  assert(is_inter_compound_mode(mode));
  return lut[mode];
}

Yue Chen's avatar
Yue Chen committed
128
static INLINE int have_newmv_in_inter_mode(PREDICTION_MODE mode) {
clang-format's avatar
clang-format committed
129
  return (mode == NEWMV || mode == NEWFROMNEARMV || mode == NEW_NEWMV ||
130
131
          mode == NEAREST_NEWMV || mode == NEW_NEARESTMV ||
          mode == NEAR_NEWMV || mode == NEW_NEARMV);
Jingning Han's avatar
Jingning Han committed
132
}
133
134
135
136
137
#else

static INLINE int have_newmv_in_inter_mode(PREDICTION_MODE mode) {
  return (mode == NEWMV);
}
Yue Chen's avatar
Yue Chen committed
138
#endif  // CONFIG_EXT_INTER
Jingning Han's avatar
Jingning Han committed
139
140
141
142
143
144
145
146

/* For keyframes, intra block modes are predicted by the (already decoded)
   modes for the Y blocks to the left and above us; for interframes, there
   is a single probability table. */

typedef struct {
  PREDICTION_MODE as_mode;
  int_mv as_mv[2];  // first, second inter predictor motion vectors
Jingning Han's avatar
Jingning Han committed
147
#if CONFIG_REF_MV
148
  int_mv pred_mv_s8[2];
Jingning Han's avatar
Jingning Han committed
149
#endif
Yue Chen's avatar
Yue Chen committed
150
151
152
#if CONFIG_EXT_INTER
  int_mv ref_mv[2];
#endif  // CONFIG_EXT_INTER
Jingning Han's avatar
Jingning Han committed
153
154
155
156
} b_mode_info;

typedef int8_t MV_REFERENCE_FRAME;

hui su's avatar
hui su committed
157
158
159
typedef struct {
  // Number of base colors for Y (0) and UV (1)
  uint8_t palette_size[2];
clang-format's avatar
clang-format committed
160
// Value of base colors for Y, U, and V
hui su's avatar
hui su committed
161
162
163
164
165
166
167
168
169
#if CONFIG_VP9_HIGHBITDEPTH
  uint16_t palette_colors[3 * PALETTE_MAX_SIZE];
#else
  uint8_t palette_colors[3 * PALETTE_MAX_SIZE];
#endif  // CONFIG_VP9_HIGHBITDEPTH
  // Only used by encoder to store the color index of the top left pixel.
  // TODO(huisu): move this to encoder
  uint8_t palette_first_color_idx[2];
} PALETTE_MODE_INFO;
hui su's avatar
hui su committed
170

hui su's avatar
hui su committed
171
172
173
174
175
176
177
178
#if CONFIG_EXT_INTRA
typedef struct {
  // 1: an ext intra mode is used; 0: otherwise.
  uint8_t use_ext_intra_mode[PLANE_TYPES];
  EXT_INTRA_MODE ext_intra_mode[PLANE_TYPES];
} EXT_INTRA_MODE_INFO;
#endif  // CONFIG_EXT_INTRA

Jingning Han's avatar
Jingning Han committed
179
180
181
182
183
184
// This structure now relates to 8x8 block regions.
typedef struct {
  // Common for both INTER and INTRA blocks
  BLOCK_SIZE sb_type;
  PREDICTION_MODE mode;
  TX_SIZE tx_size;
185
#if CONFIG_VAR_TX
186
187
  // TODO(jingning): This effectively assigned a separate entry for each
  // 8x8 block. Apparently it takes much more space than needed.
188
  TX_SIZE inter_tx_size[MAX_MIB_SIZE][MAX_MIB_SIZE];
189
#endif
Jingning Han's avatar
Jingning Han committed
190
  int8_t skip;
191
  int8_t has_no_coeffs;
Jingning Han's avatar
Jingning Han committed
192
  int8_t segment_id;
193
194
195
#if CONFIG_SUPERTX
  // Minimum of all segment IDs under the current supertx block.
  int8_t segment_id_supertx;
clang-format's avatar
clang-format committed
196
#endif                      // CONFIG_SUPERTX
Jingning Han's avatar
Jingning Han committed
197
198
199
200
  int8_t seg_id_predicted;  // valid only when temporal_update is enabled

  // Only for INTRA blocks
  PREDICTION_MODE uv_mode;
hui su's avatar
hui su committed
201
  PALETTE_MODE_INFO palette_mode_info;
Jingning Han's avatar
Jingning Han committed
202

clang-format's avatar
clang-format committed
203
// Only for INTER blocks
204
205
206
#if CONFIG_DUAL_FILTER
  INTERP_FILTER interp_filter[4];
#else
Jingning Han's avatar
Jingning Han committed
207
  INTERP_FILTER interp_filter;
208
#endif
Jingning Han's avatar
Jingning Han committed
209
  MV_REFERENCE_FRAME ref_frame[2];
hui su's avatar
hui su committed
210
  TX_TYPE tx_type;
Jingning Han's avatar
Jingning Han committed
211

hui su's avatar
hui su committed
212
213
#if CONFIG_EXT_INTRA
  EXT_INTRA_MODE_INFO ext_intra_mode_info;
hui su's avatar
hui su committed
214
  int8_t angle_delta[2];
215
216
  // To-Do (huisu): this may be replaced by interp_filter
  INTRA_FILTER intra_filter;
hui su's avatar
hui su committed
217
218
#endif  // CONFIG_EXT_INTRA

219
#if CONFIG_EXT_INTER
220
  INTERINTRA_MODE interintra_mode;
221
222
223
  // TODO(debargha): Consolidate these flags
  int use_wedge_interintra;
  int interintra_wedge_index;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
224
  int interintra_wedge_sign;
225
226
  int use_wedge_interinter;
  int interinter_wedge_index;
Debargha Mukherjee's avatar
Debargha Mukherjee committed
227
  int interinter_wedge_sign;
228
#endif  // CONFIG_EXT_INTER
229
  MOTION_VARIATION motion_variation;
Jingning Han's avatar
Jingning Han committed
230
  int_mv mv[2];
231
  int_mv pred_mv[2];
232
233
234
#if CONFIG_REF_MV
  uint8_t ref_mv_idx;
#endif
235
236
237
#if CONFIG_EXT_PARTITION_TYPES
  PARTITION_TYPE partition;
#endif
238
239
240
241
#if CONFIG_NEW_QUANT
  int dq_off_index;
  int send_dq_bit;
#endif  // CONFIG_NEW_QUANT
Jingning Han's avatar
Jingning Han committed
242
243
244
245
246
247
248
249
} MB_MODE_INFO;

typedef struct MODE_INFO {
  MB_MODE_INFO mbmi;
  b_mode_info bmi[4];
} MODE_INFO;

static INLINE PREDICTION_MODE get_y_mode(const MODE_INFO *mi, int block) {
clang-format's avatar
clang-format committed
250
  return mi->mbmi.sb_type < BLOCK_8X8 ? mi->bmi[block].as_mode : mi->mbmi.mode;
Jingning Han's avatar
Jingning Han committed
251
252
253
254
255
256
257
258
259
260
261
}

static INLINE int is_inter_block(const MB_MODE_INFO *mbmi) {
  return mbmi->ref_frame[0] > INTRA_FRAME;
}

static INLINE int has_second_ref(const MB_MODE_INFO *mbmi) {
  return mbmi->ref_frame[1] > INTRA_FRAME;
}

PREDICTION_MODE vp10_left_block_mode(const MODE_INFO *cur_mi,
clang-format's avatar
clang-format committed
262
                                     const MODE_INFO *left_mi, int b);
Jingning Han's avatar
Jingning Han committed
263
264

PREDICTION_MODE vp10_above_block_mode(const MODE_INFO *cur_mi,
clang-format's avatar
clang-format committed
265
                                      const MODE_INFO *above_mi, int b);
Jingning Han's avatar
Jingning Han committed
266

clang-format's avatar
clang-format committed
267
enum mv_precision { MV_PRECISION_Q3, MV_PRECISION_Q4 };
Jingning Han's avatar
Jingning Han committed
268
269
270

struct buf_2d {
  uint8_t *buf;
271
272
273
  uint8_t *buf0;
  int width;
  int height;
Jingning Han's avatar
Jingning Han committed
274
275
276
  int stride;
};

Angie Chiang's avatar
Angie Chiang committed
277
typedef struct macroblockd_plane {
Jingning Han's avatar
Jingning Han committed
278
279
280
281
282
283
284
285
286
  tran_low_t *dqcoeff;
  PLANE_TYPE plane_type;
  int subsampling_x;
  int subsampling_y;
  struct buf_2d dst;
  struct buf_2d pre[2];
  ENTROPY_CONTEXT *above_context;
  ENTROPY_CONTEXT *left_context;
  int16_t seg_dequant[MAX_SEGMENTS][2];
287
#if CONFIG_NEW_QUANT
288
  dequant_val_type_nuq
clang-format's avatar
clang-format committed
289
      seg_dequant_nuq[MAX_SEGMENTS][QUANT_PROFILES][COEF_BANDS];
290
#endif
hui su's avatar
hui su committed
291
  uint8_t *color_index_map;
Jingning Han's avatar
Jingning Han committed
292
293
294
295
296
297
298
299

  // number of 4x4s in current block
  uint16_t n4_w, n4_h;
  // log2 of n4_w, n4_h
  uint8_t n4_wl, n4_hl;

  // encoder
  const int16_t *dequant;
300
#if CONFIG_NEW_QUANT
clang-format's avatar
clang-format committed
301
  const dequant_val_type_nuq *dequant_val_nuq[QUANT_PROFILES];
302
#endif  // CONFIG_NEW_QUANT
Angie Chiang's avatar
Angie Chiang committed
303
} MACROBLOCKD_PLANE;
Jingning Han's avatar
Jingning Han committed
304

clang-format's avatar
clang-format committed
305
#define BLOCK_OFFSET(x, i) ((x) + (i)*16)
Jingning Han's avatar
Jingning Han committed
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

typedef struct RefBuffer {
  // TODO(dkovalev): idx is not really required and should be removed, now it
  // is used in vp10_onyxd_if.c
  int idx;
  YV12_BUFFER_CONFIG *buf;
  struct scale_factors sf;
} RefBuffer;

typedef struct macroblockd {
  struct macroblockd_plane plane[MAX_MB_PLANE];
  uint8_t bmode_blocks_wl;
  uint8_t bmode_blocks_hl;

  FRAME_COUNTS *counts;
  TileInfo tile;

  int mi_stride;

  MODE_INFO **mi;
  MODE_INFO *left_mi;
  MODE_INFO *above_mi;
  MB_MODE_INFO *left_mbmi;
  MB_MODE_INFO *above_mbmi;

  int up_available;
  int left_available;

  const vpx_prob (*partition_probs)[PARTITION_TYPES - 1];

  /* Distance of MB away from frame edges */
  int mb_to_left_edge;
  int mb_to_right_edge;
  int mb_to_top_edge;
  int mb_to_bottom_edge;

  FRAME_CONTEXT *fc;

  /* pointers to reference frames */
  RefBuffer *block_refs[2];

  /* pointer to current frame */
  const YV12_BUFFER_CONFIG *cur_buf;

  ENTROPY_CONTEXT *above_context[MAX_MB_PLANE];
351
  ENTROPY_CONTEXT left_context[MAX_MB_PLANE][2 * MAX_MIB_SIZE];
Jingning Han's avatar
Jingning Han committed
352
353

  PARTITION_CONTEXT *above_seg_context;
354
  PARTITION_CONTEXT left_seg_context[MAX_MIB_SIZE];
Jingning Han's avatar
Jingning Han committed
355

356
357
358
#if CONFIG_VAR_TX
  TXFM_CONTEXT *above_txfm_context;
  TXFM_CONTEXT *left_txfm_context;
359
  TXFM_CONTEXT left_txfm_context_buffer[MAX_MIB_SIZE];
360

361
  TX_SIZE max_tx_size;
362
363
364
#if CONFIG_SUPERTX
  TX_SIZE supertx_size;
#endif
365
366
#endif

367
368
369
  // dimension in the unit of 8x8 block of the current block
  uint8_t n8_w, n8_h;

370
#if CONFIG_REF_MV
371
372
  uint8_t ref_mv_count[MODE_CTX_REF_FRAMES];
  CANDIDATE_MV ref_mv_stack[MODE_CTX_REF_FRAMES][MAX_REF_MV_STACK_SIZE];
373
  uint8_t is_sec_rect;
374
375
#endif

Jingning Han's avatar
Jingning Han committed
376
377
378
379
380
#if CONFIG_VP9_HIGHBITDEPTH
  /* Bit depth: 8, 10, 12 */
  int bd;
#endif

381
  int lossless[MAX_SEGMENTS];
Jingning Han's avatar
Jingning Han committed
382
383
384
  int corrupted;

  struct vpx_internal_error_info *error_info;
385
386
387
#if CONFIG_GLOBAL_MOTION
  Global_Motion_Params *global_motion;
#endif  // CONFIG_GLOBAL_MOTION
Jingning Han's avatar
Jingning Han committed
388
389
390
391
} MACROBLOCKD;

static INLINE BLOCK_SIZE get_subsize(BLOCK_SIZE bsize,
                                     PARTITION_TYPE partition) {
392
393
394
395
  if (partition == PARTITION_INVALID)
    return PARTITION_INVALID;
  else
    return subsize_lookup[partition][bsize];
396
397
}

398
static const TX_TYPE intra_mode_to_tx_type_context[INTRA_MODES] = {
Jingning Han's avatar
Jingning Han committed
399
400
401
402
403
404
405
406
407
408
409
410
  DCT_DCT,    // DC
  ADST_DCT,   // V
  DCT_ADST,   // H
  DCT_DCT,    // D45
  ADST_ADST,  // D135
  ADST_DCT,   // D117
  DCT_ADST,   // D153
  DCT_ADST,   // D207
  ADST_DCT,   // D63
  ADST_ADST,  // TM
};

411
412
#if CONFIG_SUPERTX
static INLINE int supertx_enabled(const MB_MODE_INFO *mbmi) {
clang-format's avatar
clang-format committed
413
414
  return (int)mbmi->tx_size > VPXMIN(b_width_log2_lookup[mbmi->sb_type],
                                     b_height_log2_lookup[mbmi->sb_type]);
415
416
417
}
#endif  // CONFIG_SUPERTX

418
419
420
421
422
423
424
425
426
427
428
429
static INLINE int get_tx1d_width(TX_SIZE tx_size) {
  return num_4x4_blocks_wide_txsize_lookup[tx_size] << 2;
}

static INLINE int get_tx1d_height(TX_SIZE tx_size) {
  return num_4x4_blocks_high_txsize_lookup[tx_size] << 2;
}

static INLINE int get_tx2d_size(TX_SIZE tx_size) {
  return num_4x4_blocks_txsize_lookup[tx_size] << 4;
}

430
#if CONFIG_EXT_TX
clang-format's avatar
clang-format committed
431
#define ALLOW_INTRA_EXT_TX 1
432
// whether masked transforms are used for 32X32
clang-format's avatar
clang-format committed
433
#define USE_MSKTX_FOR_32X32 0
434
#define USE_REDUCED_TXSET_FOR_16X16 1
435

clang-format's avatar
clang-format committed
436
437
static const int num_ext_tx_set_inter[EXT_TX_SETS_INTER] = { 1, 16, 12, 2 };
static const int num_ext_tx_set_intra[EXT_TX_SETS_INTRA] = { 1, 7, 5 };
438

439
#if EXT_TX_SIZES == 4
clang-format's avatar
clang-format committed
440
static INLINE int get_ext_tx_set(TX_SIZE tx_size, BLOCK_SIZE bs, int is_inter) {
441
  tx_size = txsize_sqr_map[tx_size];
442
  if (tx_size > TX_32X32 || bs < BLOCK_8X8) return 0;
443
#if USE_REDUCED_TXSET_FOR_16X16
clang-format's avatar
clang-format committed
444
  if (tx_size == TX_32X32) return is_inter ? 3 - USE_MSKTX_FOR_32X32 : 0;
445
446
  return (tx_size == TX_16X16 ? 2 : 1);
#else
clang-format's avatar
clang-format committed
447
  if (tx_size == TX_32X32) return is_inter ? 3 - 2 * USE_MSKTX_FOR_32X32 : 0;
448
449
  return (tx_size == TX_16X16 && !is_inter ? 2 : 1);
#endif  // USE_REDUCED_TXSET_FOR_16X16
450
451
452
}

static const int use_intra_ext_tx_for_txsize[EXT_TX_SETS_INTRA][TX_SIZES] = {
clang-format's avatar
clang-format committed
453
454
455
  { 0, 0, 0, 0 },  // unused
  { 1, 1, 0, 0 },
  { 0, 0, 1, 0 },
456
457
458
};

static const int use_inter_ext_tx_for_txsize[EXT_TX_SETS_INTER][TX_SIZES] = {
clang-format's avatar
clang-format committed
459
460
461
462
  { 0, 0, 0, 0 },  // unused
  { 1, 1, (!USE_REDUCED_TXSET_FOR_16X16), USE_MSKTX_FOR_32X32 },
  { 0, 0, USE_REDUCED_TXSET_FOR_16X16, 0 },
  { 0, 0, 0, (!USE_MSKTX_FOR_32X32) },
463
464
465
466
};

#else  // EXT_TX_SIZES == 4

clang-format's avatar
clang-format committed
467
468
static INLINE int get_ext_tx_set(TX_SIZE tx_size, BLOCK_SIZE bs, int is_inter) {
  (void)is_inter;
469
  tx_size = txsize_sqr_map[tx_size];
470
471
  if (tx_size > TX_32X32 || bs < BLOCK_8X8) return 0;
  if (tx_size == TX_32X32) return 0;
472
473
474
475
476
#if USE_REDUCED_TXSET_FOR_16X16
  return (tx_size == TX_16X16 ? 2 : 1);
#else
  return (tx_size == TX_16X16 && !is_inter ? 2 : 1);
#endif  // USE_REDUCED_TXSET_FOR_16X16
477
478
}

479
static const int use_intra_ext_tx_for_txsize[EXT_TX_SETS_INTRA][TX_SIZES] = {
clang-format's avatar
clang-format committed
480
481
482
  { 0, 0, 0, 0 },  // unused
  { 1, 1, 0, 0 },
  { 0, 0, 1, 0 },
483
484
};

485
static const int use_inter_ext_tx_for_txsize[EXT_TX_SETS_INTER][TX_SIZES] = {
clang-format's avatar
clang-format committed
486
487
488
489
  { 0, 0, 0, 0 },  // unused
  { 1, 1, (!USE_REDUCED_TXSET_FOR_16X16), 0 },
  { 0, 0, USE_REDUCED_TXSET_FOR_16X16, 0 },
  { 0, 0, 0, 1 },
490
};
491
#endif  // EXT_TX_SIZES == 4
492

493
// Transform types used in each intra set
494
static const int ext_tx_used_intra[EXT_TX_SETS_INTRA][TX_TYPES] = {
clang-format's avatar
clang-format committed
495
496
497
  { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0 },
  { 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
498
499
};

500
// Transform types used in each inter set
501
static const int ext_tx_used_inter[EXT_TX_SETS_INTER][TX_TYPES] = {
clang-format's avatar
clang-format committed
502
503
504
505
  { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
  { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
506
};
507

508
509
510
// 1D Transforms used in inter set, this needs to be changed if
// ext_tx_used_inter is changed
static const int ext_tx_used_inter_1D[EXT_TX_SETS_INTER][TX_TYPES_1D] = {
clang-format's avatar
clang-format committed
511
  { 1, 0, 0, 0 }, { 1, 1, 1, 1 }, { 1, 1, 1, 1 }, { 1, 0, 0, 1 },
512
513
};

514
515
516
517
518
static INLINE int get_ext_tx_types(TX_SIZE tx_size, BLOCK_SIZE bs,
                                   int is_inter) {
  const int set = get_ext_tx_set(tx_size, bs, is_inter);
  return is_inter ? num_ext_tx_set_inter[set] : num_ext_tx_set_intra[set];
}
519
520
#endif  // CONFIG_EXT_TX

hui su's avatar
hui su committed
521
#if CONFIG_EXT_INTRA
hui su's avatar
hui su committed
522
523
524
525
#define ALLOW_FILTER_INTRA_MODES 1
#define ANGLE_STEP 3
#define MAX_ANGLE_DELTAS 3

526
extern const int16_t dr_intra_derivative[90];
527

528
static const uint8_t mode_to_angle_map[INTRA_MODES] = {
clang-format's avatar
clang-format committed
529
  0, 90, 180, 45, 135, 111, 157, 203, 67, 0,
hui su's avatar
hui su committed
530
};
hui su's avatar
hui su committed
531
532
533
534
535
536
537
538
539
540
541
542
543

static const TX_TYPE filter_intra_mode_to_tx_type_lookup[FILTER_INTRA_MODES] = {
  DCT_DCT,    // FILTER_DC
  ADST_DCT,   // FILTER_V
  DCT_ADST,   // FILTER_H
  DCT_DCT,    // FILTER_D45
  ADST_ADST,  // FILTER_D135
  ADST_DCT,   // FILTER_D117
  DCT_ADST,   // FILTER_D153
  DCT_ADST,   // FILTER_D207
  ADST_DCT,   // FILTER_D63
  ADST_ADST,  // FILTER_TM
};
544

Alex Converse's avatar
Alex Converse committed
545
int vp10_is_intra_filter_switchable(int angle);
hui su's avatar
hui su committed
546
547
#endif  // CONFIG_EXT_INTRA

Yunqing Wang's avatar
Yunqing Wang committed
548
549
550
#if CONFIG_EXT_TILE
#define FIXED_TX_TYPE 1
#else
551
#define FIXED_TX_TYPE 0
Yunqing Wang's avatar
Yunqing Wang committed
552
#endif
553
554

static INLINE TX_TYPE get_default_tx_type(PLANE_TYPE plane_type,
clang-format's avatar
clang-format committed
555
556
                                          const MACROBLOCKD *xd, int block_idx,
                                          TX_SIZE tx_size) {
557
558
559
560
561
562
  const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;

  if (is_inter_block(mbmi) || plane_type != PLANE_TYPE_Y ||
      xd->lossless[mbmi->segment_id] || tx_size >= TX_32X32)
    return DCT_DCT;

clang-format's avatar
clang-format committed
563
564
565
  return intra_mode_to_tx_type_context[plane_type == PLANE_TYPE_Y
                                           ? get_y_mode(xd->mi[0], block_idx)
                                           : mbmi->uv_mode];
566
567
}

clang-format's avatar
clang-format committed
568
static INLINE TX_TYPE get_tx_type(PLANE_TYPE plane_type, const MACROBLOCKD *xd,
hui su's avatar
hui su committed
569
                                  int block_idx, TX_SIZE tx_size) {
Jingning Han's avatar
Jingning Han committed
570
  const MODE_INFO *const mi = xd->mi[0];
hui su's avatar
hui su committed
571
  const MB_MODE_INFO *const mbmi = &mi->mbmi;
hui su's avatar
hui su committed
572

573
574
575
  if (FIXED_TX_TYPE)
    return get_default_tx_type(plane_type, xd, block_idx, tx_size);

hui su's avatar
hui su committed
576
#if CONFIG_EXT_INTRA
hui su's avatar
hui su committed
577
578
579
580
581
  if (!is_inter_block(mbmi)) {
    const int use_ext_intra_mode_info =
        mbmi->ext_intra_mode_info.use_ext_intra_mode[plane_type];
    const EXT_INTRA_MODE ext_intra_mode =
        mbmi->ext_intra_mode_info.ext_intra_mode[plane_type];
clang-format's avatar
clang-format committed
582
583
584
    const PREDICTION_MODE mode = (plane_type == PLANE_TYPE_Y)
                                     ? get_y_mode(mi, block_idx)
                                     : mbmi->uv_mode;
hui su's avatar
hui su committed
585

clang-format's avatar
clang-format committed
586
    if (xd->lossless[mbmi->segment_id] || tx_size >= TX_32X32) return DCT_DCT;
hui su's avatar
hui su committed
587
588

#if CONFIG_EXT_TX
589
590
#if ALLOW_INTRA_EXT_TX
    if (mbmi->sb_type >= BLOCK_8X8 && plane_type == PLANE_TYPE_Y)
hui su's avatar
hui su committed
591
      return mbmi->tx_type;
592
#endif  // ALLOW_INTRA_EXT_TX
hui su's avatar
hui su committed
593
#endif  // CONFIG_EXT_TX
hui su's avatar
hui su committed
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614

    if (use_ext_intra_mode_info)
      return filter_intra_mode_to_tx_type_lookup[ext_intra_mode];

    if (mode == DC_PRED) {
      return DCT_DCT;
    } else if (mode == TM_PRED) {
      return ADST_ADST;
    } else {
      int angle = mode_to_angle_map[mode];
      if (mbmi->sb_type >= BLOCK_8X8)
        angle += mbmi->angle_delta[plane_type] * ANGLE_STEP;
      assert(angle > 0 && angle < 270);
      if (angle == 135)
        return ADST_ADST;
      else if (angle < 45 || angle > 225)
        return DCT_DCT;
      else if (angle < 135)
        return ADST_DCT;
      else
        return DCT_ADST;
hui su's avatar
hui su committed
615
616
617
    }
  }
#endif  // CONFIG_EXT_INTRA
Jingning Han's avatar
Jingning Han committed
618

hui su's avatar
hui su committed
619
#if CONFIG_EXT_TX
620
#if EXT_TX_SIZES == 4
clang-format's avatar
clang-format committed
621
  if (xd->lossless[mbmi->segment_id] || txsize_sqr_map[tx_size] > TX_32X32 ||
622
      (txsize_sqr_map[tx_size] >= TX_32X32 && !is_inter_block(mbmi)))
623
#else
624
  if (xd->lossless[mbmi->segment_id] || txsize_sqr_map[tx_size] >= TX_32X32)
625
#endif
hui su's avatar
hui su committed
626
    return DCT_DCT;
627
  if (mbmi->sb_type >= BLOCK_8X8) {
628
    if (plane_type == PLANE_TYPE_Y) {
629
630
631
632
#if !ALLOW_INTRA_EXT_TX
      if (is_inter_block(mbmi))
#endif  // ALLOW_INTRA_EXT_TX
        return mbmi->tx_type;
633
    }
634
635
    if (is_inter_block(mbmi))
      // UV Inter only
clang-format's avatar
clang-format committed
636
637
638
      return (mbmi->tx_type == IDTX && txsize_sqr_map[tx_size] == TX_32X32)
                 ? DCT_DCT
                 : mbmi->tx_type;
639
  }
640

641
642
  // Sub8x8-Inter/Intra OR UV-Intra
  if (is_inter_block(mbmi))  // Sub8x8-Inter
643
    return DCT_DCT;
644
  else  // Sub8x8 Intra OR UV-Intra
clang-format's avatar
clang-format committed
645
646
647
    return intra_mode_to_tx_type_context[plane_type == PLANE_TYPE_Y
                                             ? get_y_mode(mi, block_idx)
                                             : mbmi->uv_mode];
648
#else   // CONFIG_EXT_TX
clang-format's avatar
clang-format committed
649
  (void)block_idx;
650
  if (plane_type != PLANE_TYPE_Y || xd->lossless[mbmi->segment_id] ||
651
      txsize_sqr_map[tx_size] >= TX_32X32)
Jingning Han's avatar
Jingning Han committed
652
    return DCT_DCT;
653
  return mbmi->tx_type;
hui su's avatar
hui su committed
654
#endif  // CONFIG_EXT_TX
Jingning Han's avatar
Jingning Han committed
655
656
657
658
659
660
661
662
663
664
}

void vp10_setup_block_planes(MACROBLOCKD *xd, int ss_x, int ss_y);

static INLINE TX_SIZE get_uv_tx_size_impl(TX_SIZE y_tx_size, BLOCK_SIZE bsize,
                                          int xss, int yss) {
  if (bsize < BLOCK_8X8) {
    return TX_4X4;
  } else {
    const BLOCK_SIZE plane_bsize = ss_size_lookup[bsize][xss][yss];
665
    return VPXMIN(y_tx_size, max_txsize_lookup[plane_bsize]);
Jingning Han's avatar
Jingning Han committed
666
667
668
669
670
  }
}

static INLINE TX_SIZE get_uv_tx_size(const MB_MODE_INFO *mbmi,
                                     const struct macroblockd_plane *pd) {
671
#if CONFIG_SUPERTX
hui su's avatar
hui su committed
672
  if (supertx_enabled(mbmi))
673
    return uvsupertx_size_lookup[mbmi->tx_size][pd->subsampling_x]
clang-format's avatar
clang-format committed
674
                                [pd->subsampling_y];
hui su's avatar
hui su committed
675
#endif  // CONFIG_SUPERTX
Jingning Han's avatar
Jingning Han committed
676
677
678
679
  return get_uv_tx_size_impl(mbmi->tx_size, mbmi->sb_type, pd->subsampling_x,
                             pd->subsampling_y);
}

clang-format's avatar
clang-format committed
680
681
static INLINE BLOCK_SIZE
get_plane_block_size(BLOCK_SIZE bsize, const struct macroblockd_plane *pd) {
Jingning Han's avatar
Jingning Han committed
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
  return ss_size_lookup[bsize][pd->subsampling_x][pd->subsampling_y];
}

static INLINE void reset_skip_context(MACROBLOCKD *xd, BLOCK_SIZE bsize) {
  int i;
  for (i = 0; i < MAX_MB_PLANE; i++) {
    struct macroblockd_plane *const pd = &xd->plane[i];
    const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
    memset(pd->above_context, 0,
           sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_wide_lookup[plane_bsize]);
    memset(pd->left_context, 0,
           sizeof(ENTROPY_CONTEXT) * num_4x4_blocks_high_lookup[plane_bsize]);
  }
}

typedef void (*foreach_transformed_block_visitor)(int plane, int block,
698
                                                  int blk_row, int blk_col,
Jingning Han's avatar
Jingning Han committed
699
                                                  BLOCK_SIZE plane_bsize,
clang-format's avatar
clang-format committed
700
                                                  TX_SIZE tx_size, void *arg);
Jingning Han's avatar
Jingning Han committed
701
702
703
704
705

void vp10_foreach_transformed_block_in_plane(
    const MACROBLOCKD *const xd, BLOCK_SIZE bsize, int plane,
    foreach_transformed_block_visitor visit, void *arg);

clang-format's avatar
clang-format committed
706
707
708
709
void vp10_foreach_transformed_block(const MACROBLOCKD *const xd,
                                    BLOCK_SIZE bsize,
                                    foreach_transformed_block_visitor visit,
                                    void *arg);
Jingning Han's avatar
Jingning Han committed
710
711

void vp10_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
clang-format's avatar
clang-format committed
712
713
                       BLOCK_SIZE plane_bsize, TX_SIZE tx_size, int has_eob,
                       int aoff, int loff);
Jingning Han's avatar
Jingning Han committed
714

715
716
#if CONFIG_EXT_INTER
static INLINE int is_interintra_allowed_bsize(const BLOCK_SIZE bsize) {
717
  // TODO(debargha): Should this be bsize < BLOCK_LARGEST?
718
719
720
721
722
723
724
725
726
727
728
729
  return (bsize >= BLOCK_8X8) && (bsize < BLOCK_64X64);
}

static INLINE int is_interintra_allowed_mode(const PREDICTION_MODE mode) {
  return (mode >= NEARESTMV) && (mode <= NEWMV);
}

static INLINE int is_interintra_allowed_ref(const MV_REFERENCE_FRAME rf[2]) {
  return (rf[0] > INTRA_FRAME) && (rf[1] <= INTRA_FRAME);
}

static INLINE int is_interintra_allowed(const MB_MODE_INFO *mbmi) {
clang-format's avatar
clang-format committed
730
731
732
  return is_interintra_allowed_bsize(mbmi->sb_type) &&
         is_interintra_allowed_mode(mbmi->mode) &&
         is_interintra_allowed_ref(mbmi->ref_frame);
733
734
}

735
736
737
static INLINE int is_interintra_allowed_bsize_group(const int group) {
  int i;
  for (i = 0; i < BLOCK_SIZES; i++) {
clang-format's avatar
clang-format committed
738
    if (size_group_lookup[i] == group && is_interintra_allowed_bsize(i))
739
740
741
742
743
      return 1;
  }
  return 0;
}

744
745
746
747
748
static INLINE int is_interintra_pred(const MB_MODE_INFO *mbmi) {
  return (mbmi->ref_frame[1] == INTRA_FRAME) && is_interintra_allowed(mbmi);
}
#endif  // CONFIG_EXT_INTER

749
750
#if CONFIG_OBMC || CONFIG_WARPED_MOTION
static INLINE int is_motvar_allowed(const MB_MODE_INFO *mbmi) {
751
752
753
#if CONFIG_EXT_INTER
  return (mbmi->sb_type >= BLOCK_8X8 && mbmi->ref_frame[1] != INTRA_FRAME);
#else
754
  return (mbmi->sb_type >= BLOCK_8X8);
755
#endif  // CONFIG_EXT_INTER
756
757
}

758
#if CONFIG_OBMC
759
760
761
762
static INLINE int is_neighbor_overlappable(const MB_MODE_INFO *mbmi) {
  return (is_inter_block(mbmi));
}
#endif  // CONFIG_OBMC
763
#endif  // CONFIG_OBMC || CONFIG_WARPED_MOTION
764

Jingning Han's avatar
Jingning Han committed
765
766
767
768
#ifdef __cplusplus
}  // extern "C"
#endif

769
#endif  // VP10_COMMON_BLOCKD_H_