context.rs 124 KB
Newer Older
Thomas Daede's avatar
Thomas Daede committed
1
// Copyright (c) 2017-2018, The rav1e contributors. All rights reserved
Raphaël Zumer's avatar
Raphaël Zumer committed
2
//
3
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.

Thomas Daede's avatar
Thomas Daede committed
10
11
12
13
14
#![allow(safe_extern_statics)]
#![allow(non_upper_case_globals)]
#![allow(dead_code)]
#![allow(non_camel_case_types)]

Raphaël Zumer's avatar
Raphaël Zumer committed
15
use crate::ec::Writer;
16
use crate::ec::OD_BITRES;
17
use crate::encoder::FrameInvariants;
Raphaël Zumer's avatar
Raphaël Zumer committed
18
use crate::entropymode::*;
19
use crate::header::ReferenceMode;
Raphaël Zumer's avatar
Raphaël Zumer committed
20
21
use crate::partition::BlockSize::*;
use crate::partition::PredictionMode::*;
Thomas Daede's avatar
Thomas Daede committed
22
use crate::partition::RefType::*;
Raphaël Zumer's avatar
Raphaël Zumer committed
23
24
25
26
27
28
use crate::partition::TxSize::*;
use crate::partition::TxType::*;
use crate::partition::*;
use crate::lrf::*;
use crate::plane::*;
use crate::scan_order::*;
29
use crate::tiling::*;
Raphaël Zumer's avatar
Raphaël Zumer committed
30
use crate::token_cdfs::*;
31
use crate::util::{AlignedArray, clamp, msb, Pixel, UninitializedAlignedArray};
Thomas Daede's avatar
Thomas Daede committed
32

Raphaël Zumer's avatar
Raphaël Zumer committed
33
use std::*;
Romain Vimont's avatar
Romain Vimont committed
34
use std::ops::{Index, IndexMut};
35
use arrayvec::*;
36

37
pub const PLANES: usize = 3;
Thomas Daede's avatar
Thomas Daede committed
38
39

const PARTITION_PLOFFSET: usize = 4;
Thomas Daede's avatar
Thomas Daede committed
40
41
const PARTITION_BLOCK_SIZES: usize = 4 + 1;
const PARTITION_CONTEXTS_PRIMARY: usize = PARTITION_BLOCK_SIZES * PARTITION_PLOFFSET;
42
pub const PARTITION_CONTEXTS: usize = PARTITION_CONTEXTS_PRIMARY;
43
pub const PARTITION_TYPES: usize = 4;
Thomas Daede's avatar
Thomas Daede committed
44

45
pub const MI_SIZE_LOG2: usize = 2;
46
pub const MI_SIZE: usize = (1 << MI_SIZE_LOG2);
Thomas Daede's avatar
Thomas Daede committed
47
const MAX_MIB_SIZE_LOG2: usize = (MAX_SB_SIZE_LOG2 - MI_SIZE_LOG2);
48
pub const MAX_MIB_SIZE: usize = (1 << MAX_MIB_SIZE_LOG2);
49
pub const MAX_MIB_MASK: usize = (MAX_MIB_SIZE - 1);
Thomas Daede's avatar
Thomas Daede committed
50
51

const MAX_SB_SIZE_LOG2: usize = 6;
52
pub const MAX_SB_SIZE: usize = (1 << MAX_SB_SIZE_LOG2);
Thomas Daede's avatar
Thomas Daede committed
53
54
const MAX_SB_SQUARE: usize = (MAX_SB_SIZE * MAX_SB_SIZE);

55
pub const MAX_TX_SIZE: usize = 64;
56
57
const MAX_TX_SQUARE: usize = MAX_TX_SIZE * MAX_TX_SIZE;

Yushin Cho's avatar
Yushin Cho committed
58
pub const INTRA_MODES: usize = 13;
59
pub const UV_INTRA_MODES: usize = 14;
60

61
62
63
64
65
66
pub const CFL_JOINT_SIGNS: usize = 8;
pub const CFL_ALPHA_CONTEXTS: usize = 6;
pub const CFL_ALPHABET_SIZE: usize = 16;
pub const SKIP_MODE_CONTEXTS: usize = 3;
pub const COMP_INDEX_CONTEXTS: usize = 6;
pub const COMP_GROUP_IDX_CONTEXTS: usize = 6;
67

68
69
70
71
pub const BLOCK_SIZE_GROUPS: usize = 4;
pub const MAX_ANGLE_DELTA: usize = 3;
pub const DIRECTIONAL_MODES: usize = 8;
pub const KF_MODE_CONTEXTS: usize = 5;
Thomas Daede's avatar
Thomas Daede committed
72

73
pub const EXT_PARTITION_TYPES: usize = 10;
Thomas Daede's avatar
Thomas Daede committed
74

75
pub const TX_SIZE_SQR_CONTEXTS: usize = 4; // Coded tx_size <= 32x32, so is the # of CDF contexts from tx sizes
76
77
78
79
80

pub const TX_SETS: usize = 9;
pub const TX_SETS_INTRA: usize = 3;
pub const TX_SETS_INTER: usize = 4;
pub const TXFM_PARTITION_CONTEXTS: usize = ((TxSize::TX_SIZES - TxSize::TX_8X8 as usize) * 6 - 3);
81
82
83
const MAX_REF_MV_STACK_SIZE: usize = 8;
pub const REF_CAT_LEVEL: u32 = 640;

84
85
pub const FRAME_LF_COUNT: usize = 4;
pub const MAX_LOOP_FILTER: usize = 63;
86
const DELTA_LF_SMALL: u32 = 3;
87
88
89
90
pub const DELTA_LF_PROBS: usize = DELTA_LF_SMALL as usize;

const DELTA_Q_SMALL: u32 = 3;
pub const DELTA_Q_PROBS: usize = DELTA_Q_SMALL as usize;
91

Thomas Daede's avatar
Thomas Daede committed
92
// Number of transform types in each set type
Yushin Cho's avatar
Yushin Cho committed
93
static num_tx_set: [usize; TX_SETS] =
Michael Bebenita's avatar
Michael Bebenita committed
94
  [1, 2, 5, 7, 7, 10, 12, 16, 16];
Yushin Cho's avatar
Yushin Cho committed
95
pub static av1_tx_used: [[usize; TX_TYPES]; TX_SETS] = [
Michael Bebenita's avatar
Michael Bebenita committed
96
97
98
99
100
101
102
103
104
105
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
  [1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 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, 1, 1, 0, 0, 0, 0],
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
  [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1]
];
Yushin Cho's avatar
Yushin Cho committed
106

Thomas Daede's avatar
Thomas Daede committed
107
// Maps set types above to the indices used for intra
Yushin Cho's avatar
Yushin Cho committed
108
static tx_set_index_intra: [i8; TX_SETS] =
109
  [0, -1, 2, -1, 1, -1, -1, -1, -16];
Thomas Daede's avatar
Thomas Daede committed
110
// Maps set types above to the indices used for inter
Yushin Cho's avatar
Yushin Cho committed
111
static tx_set_index_inter: [i8; TX_SETS] =
Michael Bebenita's avatar
Michael Bebenita committed
112
  [0, 3, -1, -1, -1, -1, 2, -1, 1];
113

Yushin Cho's avatar
Yushin Cho committed
114
static av1_tx_ind: [[usize; TX_TYPES]; TX_SETS] = [
Michael Bebenita's avatar
Michael Bebenita committed
115
116
117
118
119
120
121
122
123
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 3, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [1, 5, 6, 4, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0],
  [1, 5, 6, 4, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0],
  [1, 2, 3, 6, 4, 5, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0],
  [3, 4, 5, 8, 6, 7, 9, 10, 11, 0, 1, 2, 0, 0, 0, 0],
  [7, 8, 9, 12, 10, 11, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6],
  [7, 8, 9, 12, 10, 11, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6]
124
125
];

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
pub static max_txsize_rect_lookup: [TxSize; BlockSize::BLOCK_SIZES_ALL] = [
      // 4X4
      TX_4X4,
      // 4X8,    8X4,      8X8
      TX_4X8,    TX_8X4,   TX_8X8,
      // 8X16,   16X8,     16X16
      TX_8X16,   TX_16X8,  TX_16X16,
      // 16X32,  32X16,    32X32
      TX_16X32,  TX_32X16, TX_32X32,
      // 32X64,  64X32,
      TX_32X64,  TX_64X32,
      // 64X64
      TX_64X64,
      // 64x128, 128x64,   128x128
      TX_64X64,  TX_64X64, TX_64X64,
      // 4x16,   16x4,
      TX_4X16,   TX_16X4,
      // 8x32,   32x8
      TX_8X32,   TX_32X8,
      // 16x64,  64x16
      TX_16X64,  TX_64X16
];

149
pub static sub_tx_size_map: [TxSize; TxSize::TX_SIZES_ALL] = [
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
  TX_4X4,    // TX_4X4
  TX_4X4,    // TX_8X8
  TX_8X8,    // TX_16X16
  TX_16X16,  // TX_32X32
  TX_32X32,  // TX_64X64
  TX_4X4,    // TX_4X8
  TX_4X4,    // TX_8X4
  TX_8X8,    // TX_8X16
  TX_8X8,    // TX_16X8
  TX_16X16,  // TX_16X32
  TX_16X16,  // TX_32X16
  TX_32X32,  // TX_32X64
  TX_32X32,  // TX_64X32
  TX_4X8,    // TX_4X16
  TX_8X4,    // TX_16X4
  TX_8X16,   // TX_8X32
  TX_16X8,   // TX_32X8
  TX_16X32,  // TX_16X64
  TX_32X16,  // TX_64X16
];

Michael Bebenita's avatar
Michael Bebenita committed
171
static ss_size_lookup: [[[BlockSize; 2]; 2]; BlockSize::BLOCK_SIZES_ALL] = [
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
  //  ss_x == 0    ss_x == 0        ss_x == 1      ss_x == 1
  //  ss_y == 0    ss_y == 1        ss_y == 0      ss_y == 1
  [  [ BLOCK_4X4, BLOCK_4X4 ], [BLOCK_4X4, BLOCK_4X4 ] ],
  [  [ BLOCK_4X8, BLOCK_4X4 ], [BLOCK_4X4, BLOCK_4X4 ] ],
  [  [ BLOCK_8X4, BLOCK_4X4 ], [BLOCK_4X4, BLOCK_4X4 ] ],
  [  [ BLOCK_8X8, BLOCK_8X4 ], [BLOCK_4X8, BLOCK_4X4 ] ],
  [  [ BLOCK_8X16, BLOCK_8X8 ], [BLOCK_4X16, BLOCK_4X8 ] ],
  [  [ BLOCK_16X8, BLOCK_16X4 ], [BLOCK_8X8, BLOCK_8X4 ] ],
  [  [ BLOCK_16X16, BLOCK_16X8 ], [BLOCK_8X16, BLOCK_8X8 ] ],
  [  [ BLOCK_16X32, BLOCK_16X16 ], [BLOCK_8X32, BLOCK_8X16 ] ],
  [  [ BLOCK_32X16, BLOCK_32X8 ], [BLOCK_16X16, BLOCK_16X8 ] ],
  [  [ BLOCK_32X32, BLOCK_32X16 ], [BLOCK_16X32, BLOCK_16X16 ] ],
  [  [ BLOCK_32X64, BLOCK_32X32 ], [BLOCK_16X64, BLOCK_16X32 ] ],
  [  [ BLOCK_64X32, BLOCK_64X16 ], [BLOCK_32X32, BLOCK_32X16 ] ],
  [  [ BLOCK_64X64, BLOCK_64X32 ], [BLOCK_32X64, BLOCK_32X32 ] ],
187
188
  [  [ BLOCK_64X128, BLOCK_64X64 ], [ BLOCK_INVALID, BLOCK_32X64 ] ],
  [  [ BLOCK_128X64, BLOCK_INVALID ], [ BLOCK_64X64, BLOCK_64X32 ] ],
Thomas Daede's avatar
Thomas Daede committed
189
  [  [ BLOCK_128X128, BLOCK_128X64 ], [ BLOCK_64X128, BLOCK_64X64 ] ],
190
191
192
193
194
  [  [ BLOCK_4X16, BLOCK_4X8 ], [BLOCK_4X16, BLOCK_4X8 ] ],
  [  [ BLOCK_16X4, BLOCK_16X4 ], [BLOCK_8X4, BLOCK_8X4 ] ],
  [  [ BLOCK_8X32, BLOCK_8X16 ], [BLOCK_INVALID, BLOCK_4X16 ] ],
  [  [ BLOCK_32X8, BLOCK_INVALID ], [BLOCK_16X8, BLOCK_16X4 ] ],
  [  [ BLOCK_16X64, BLOCK_16X32 ], [BLOCK_INVALID, BLOCK_8X32 ] ],
195
  [  [ BLOCK_64X16, BLOCK_INVALID ], [BLOCK_32X16, BLOCK_32X8 ] ]
196
197
198
199
200
201
202
];

pub fn get_plane_block_size(bsize: BlockSize, subsampling_x: usize, subsampling_y: usize)
    -> BlockSize {
  ss_size_lookup[bsize as usize][subsampling_x][subsampling_y]
}

203
204
205
// Generates 4 bit field in which each bit set to 1 represents
// a blocksize partition  1111 means we split 64x64, 32x32, 16x16
// and 8x8.  1000 means we just split the 64x64 to 32x32
Michael Bebenita's avatar
Michael Bebenita committed
206
static partition_context_lookup: [[u8; 2]; BlockSize::BLOCK_SIZES_ALL] = [
Thomas Daede's avatar
Thomas Daede committed
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  [ 31, 31 ],  // 4X4   - {0b11111, 0b11111}
  [ 31, 30 ],  // 4X8   - {0b11111, 0b11110}
  [ 30, 31 ],  // 8X4   - {0b11110, 0b11111}
  [ 30, 30 ],  // 8X8   - {0b11110, 0b11110}
  [ 30, 28 ],  // 8X16  - {0b11110, 0b11100}
  [ 28, 30 ],  // 16X8  - {0b11100, 0b11110}
  [ 28, 28 ],  // 16X16 - {0b11100, 0b11100}
  [ 28, 24 ],  // 16X32 - {0b11100, 0b11000}
  [ 24, 28 ],  // 32X16 - {0b11000, 0b11100}
  [ 24, 24 ],  // 32X32 - {0b11000, 0b11000}
  [ 24, 16 ],  // 32X64 - {0b11000, 0b10000}
  [ 16, 24 ],  // 64X32 - {0b10000, 0b11000}
  [ 16, 16 ],  // 64X64 - {0b10000, 0b10000}
  [ 16, 0 ],   // 64X128- {0b10000, 0b00000}
  [ 0, 16 ],   // 128X64- {0b00000, 0b10000}
  [ 0, 0 ],    // 128X128-{0b00000, 0b00000}
  [ 31, 28 ],  // 4X16  - {0b11111, 0b11100}
  [ 28, 31 ],  // 16X4  - {0b11100, 0b11111}
  [ 30, 24 ],  // 8X32  - {0b11110, 0b11000}
  [ 24, 30 ],  // 32X8  - {0b11000, 0b11110}
  [ 28, 16 ],  // 16X64 - {0b11100, 0b10000}
228
  [ 16, 28 ]   // 64X16 - {0b10000, 0b11100}
229
230
];

Michael Bebenita's avatar
Michael Bebenita committed
231
static size_group_lookup: [u8; BlockSize::BLOCK_SIZES_ALL] = [
232
233
234
235
236
237
  0, 0,
  0, 1,
  1, 1,
  2, 2,
  2, 3,
  3, 3,
Thomas Daede's avatar
Thomas Daede committed
238
  3, 3, 3, 3, 0,
239
240
  0, 1,
  1, 2,
241
  2
242
243
];

Michael Bebenita's avatar
Michael Bebenita committed
244
static num_pels_log2_lookup: [u8; BlockSize::BLOCK_SIZES_ALL] = [
245
  4, 5, 5, 6, 7, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 6, 6, 8, 8, 10, 10];
246

247
pub const PLANE_TYPES: usize = 2;
Thomas Daede's avatar
Thomas Daede committed
248
const REF_TYPES: usize = 2;
249
250
251
252
253
254
255
pub const SKIP_CONTEXTS: usize = 3;
pub const INTRA_INTER_CONTEXTS: usize = 4;
pub const INTER_MODE_CONTEXTS: usize = 8;
pub const DRL_MODE_CONTEXTS: usize = 3;
pub const COMP_INTER_CONTEXTS: usize = 5;
pub const COMP_REF_TYPE_CONTEXTS: usize = 5;
pub const UNI_COMP_REF_CONTEXTS: usize = 3;
Thomas Daede's avatar
Thomas Daede committed
256

257
// Level Map
258
pub const TXB_SKIP_CONTEXTS: usize =  13;
259

260
pub const EOB_COEF_CONTEXTS: usize =  9;
261
262
263

const SIG_COEF_CONTEXTS_2D: usize =  26;
const SIG_COEF_CONTEXTS_1D: usize =  16;
264
265
pub const SIG_COEF_CONTEXTS_EOB: usize =  4;
pub const SIG_COEF_CONTEXTS: usize = SIG_COEF_CONTEXTS_2D + SIG_COEF_CONTEXTS_1D;
266
267

const COEFF_BASE_CONTEXTS: usize = SIG_COEF_CONTEXTS;
268
pub const DC_SIGN_CONTEXTS: usize =  3;
269
270
271

const BR_TMP_OFFSET: usize =  12;
const BR_REF_CAT: usize =  4;
272
pub const LEVEL_CONTEXTS: usize =  21;
273

274
pub const NUM_BASE_LEVELS: usize =  2;
275

276
pub const BR_CDF_SIZE: usize = 4;
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
const COEFF_BASE_RANGE: usize = 4 * (BR_CDF_SIZE - 1);

const COEFF_CONTEXT_BITS: usize = 6;
const COEFF_CONTEXT_MASK: usize = (1 << COEFF_CONTEXT_BITS) - 1;
const MAX_BASE_BR_RANGE: usize = COEFF_BASE_RANGE + NUM_BASE_LEVELS + 1;

const BASE_CONTEXT_POSITION_NUM: usize = 12;

// Pad 4 extra columns to remove horizontal availability check.
const TX_PAD_HOR_LOG2: usize = 2;
const TX_PAD_HOR: usize = 4;
// Pad 6 extra rows (2 on top and 4 on bottom) to remove vertical availability
// check.
const TX_PAD_TOP: usize = 2;
const TX_PAD_BOTTOM: usize = 4;
const TX_PAD_VER: usize = (TX_PAD_TOP + TX_PAD_BOTTOM);
// Pad 16 extra bytes to avoid reading overflow in SIMD optimization.
const TX_PAD_END: usize = 16;
Michael Bebenita's avatar
Michael Bebenita committed
295
296
const TX_PAD_2D: usize =
  ((MAX_TX_SIZE + TX_PAD_HOR) * (MAX_TX_SIZE + TX_PAD_VER) + TX_PAD_END);
297
298
299

const TX_CLASSES: usize = 3;

Michael Bebenita's avatar
Michael Bebenita committed
300
#[derive(Copy, Clone, PartialEq)]
301
302
303
pub enum TxClass {
  TX_CLASS_2D = 0,
  TX_CLASS_HORIZ = 1,
Michael Bebenita's avatar
Michael Bebenita committed
304
  TX_CLASS_VERT = 2
305
306
}

307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
#[derive(Copy, Clone, PartialEq)]
pub enum SegLvl {
  SEG_LVL_ALT_Q = 0,       /* Use alternate Quantizer .... */
  SEG_LVL_ALT_LF_Y_V = 1,  /* Use alternate loop filter value on y plane vertical */
  SEG_LVL_ALT_LF_Y_H = 2,  /* Use alternate loop filter value on y plane horizontal */
  SEG_LVL_ALT_LF_U = 3,    /* Use alternate loop filter value on u plane */
  SEG_LVL_ALT_LF_V = 4,    /* Use alternate loop filter value on v plane */
  SEG_LVL_REF_FRAME = 5,   /* Optional Segment reference frame */
  SEG_LVL_SKIP = 6,        /* Optional Segment (0,0) + skip mode */
  SEG_LVL_GLOBALMV = 7,
  SEG_LVL_MAX = 8
}

pub const seg_feature_bits: [u32; SegLvl::SEG_LVL_MAX as usize] =
  [ 8, 6, 6, 6, 6, 3, 0, 0 ];

pub const seg_feature_is_signed: [bool; SegLvl::SEG_LVL_MAX as usize] =
    [ true, true, true, true, true, false, false, false, ];

Raphaël Zumer's avatar
Raphaël Zumer committed
326
use crate::context::TxClass::*;
327
328

static tx_type_to_class: [TxClass; TX_TYPES] = [
Michael Bebenita's avatar
Michael Bebenita committed
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
  TX_CLASS_2D,    // DCT_DCT
  TX_CLASS_2D,    // ADST_DCT
  TX_CLASS_2D,    // DCT_ADST
  TX_CLASS_2D,    // ADST_ADST
  TX_CLASS_2D,    // FLIPADST_DCT
  TX_CLASS_2D,    // DCT_FLIPADST
  TX_CLASS_2D,    // FLIPADST_FLIPADST
  TX_CLASS_2D,    // ADST_FLIPADST
  TX_CLASS_2D,    // FLIPADST_ADST
  TX_CLASS_2D,    // IDTX
  TX_CLASS_VERT,  // V_DCT
  TX_CLASS_HORIZ, // H_DCT
  TX_CLASS_VERT,  // V_ADST
  TX_CLASS_HORIZ, // H_ADST
  TX_CLASS_VERT,  // V_FLIPADST
  TX_CLASS_HORIZ  // H_FLIPADST
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
];

static eob_to_pos_small: [u8; 33] = [
    0, 1, 2,                                        // 0-2
    3, 3,                                           // 3-4
    4, 4, 4, 4,                                     // 5-8
    5, 5, 5, 5, 5, 5, 5, 5,                         // 9-16
    6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6  // 17-32
];

static eob_to_pos_large: [u8; 17] = [
    6,                               // place holder
    7,                               // 33-64
    8,  8,                           // 65-128
    9,  9,  9,  9,                   // 129-256
    10, 10, 10, 10, 10, 10, 10, 10,  // 257-512
    11                               // 513-
];


static k_eob_group_start: [u16; 12] = [ 0, 1, 2, 3, 5, 9,
                                        17, 33, 65, 129, 257, 513 ];
static k_eob_offset_bits: [u16; 12] = [ 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ];

369
fn clip_max3(x: u8) -> u8 {
Michael Bebenita's avatar
Michael Bebenita committed
370
371
372
373
374
  if x > 3 {
    3
  } else {
    x
  }
375
}
376
377
378
379

// The ctx offset table when TX is TX_CLASS_2D.
// TX col and row indices are clamped to 4

Vladimir Kazakov's avatar
Vladimir Kazakov committed
380
#[rustfmt::skip]
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
static av1_nz_map_ctx_offset: [[[i8; 5]; 5]; TxSize::TX_SIZES_ALL] = [
  // TX_4X4
  [
    [ 0,  1,  6,  6, 0],
    [ 1,  6,  6, 21, 0],
    [ 6,  6, 21, 21, 0],
    [ 6, 21, 21, 21, 0],
    [ 0,  0,  0,  0, 0]
  ],
  // TX_8X8
  [
    [ 0,  1,  6,  6, 21],
    [ 1,  6,  6, 21, 21],
    [ 6,  6, 21, 21, 21],
    [ 6, 21, 21, 21, 21],
    [21, 21, 21, 21, 21]
  ],
  // TX_16X16
  [
    [ 0,  1,  6,  6, 21],
    [ 1,  6,  6, 21, 21],
    [ 6,  6, 21, 21, 21],
    [ 6, 21, 21, 21, 21],
    [21, 21, 21, 21, 21]
  ],
  // TX_32X32
  [
    [ 0,  1,  6,  6, 21],
    [ 1,  6,  6, 21, 21],
    [ 6,  6, 21, 21, 21],
    [ 6, 21, 21, 21, 21],
    [21, 21, 21, 21, 21]
  ],
  // TX_64X64
  [
    [ 0,  1,  6,  6, 21],
    [ 1,  6,  6, 21, 21],
    [ 6,  6, 21, 21, 21],
    [ 6, 21, 21, 21, 21],
    [21, 21, 21, 21, 21]
  ],
  // TX_4X8
  [
    [ 0, 11, 11, 11, 0],
    [11, 11, 11, 11, 0],
    [ 6,  6, 21, 21, 0],
    [ 6, 21, 21, 21, 0],
    [21, 21, 21, 21, 0]
  ],
  // TX_8X4
  [
    [ 0, 16,  6,  6, 21],
    [16, 16,  6, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21],
    [ 0,  0,  0,  0, 0]
  ],
  // TX_8X16
  [
    [ 0, 11, 11, 11, 11],
    [11, 11, 11, 11, 11],
    [ 6,  6, 21, 21, 21],
    [ 6, 21, 21, 21, 21],
    [21, 21, 21, 21, 21]
  ],
  // TX_16X8
  [
    [ 0, 16,  6,  6, 21],
    [16, 16,  6, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21]
  ],
  // TX_16X32
  [
    [ 0, 11, 11, 11, 11],
    [11, 11, 11, 11, 11],
    [ 6,  6, 21, 21, 21],
    [ 6, 21, 21, 21, 21],
    [21, 21, 21, 21, 21]
  ],
  // TX_32X16
  [
    [ 0, 16,  6,  6, 21],
    [16, 16,  6, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21]
  ],
  // TX_32X64
  [
    [ 0, 11, 11, 11, 11],
    [11, 11, 11, 11, 11],
    [ 6,  6, 21, 21, 21],
    [ 6, 21, 21, 21, 21],
    [21, 21, 21, 21, 21]
  ],
  // TX_64X32
  [
    [ 0, 16,  6,  6, 21],
    [16, 16,  6, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21]
  ],
  // TX_4X16
  [
    [ 0, 11, 11, 11, 0],
    [11, 11, 11, 11, 0],
    [ 6,  6, 21, 21, 0],
    [ 6, 21, 21, 21, 0],
    [21, 21, 21, 21, 0]
  ],
  // TX_16X4
  [
    [ 0, 16,  6,  6, 21],
    [16, 16,  6, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21],
    [ 0,  0,  0,  0, 0]
  ],
  // TX_8X32
  [
    [ 0, 11, 11, 11, 11],
    [11, 11, 11, 11, 11],
    [ 6,  6, 21, 21, 21],
    [ 6, 21, 21, 21, 21],
    [21, 21, 21, 21, 21]
  ],
  // TX_32X8
  [
    [ 0, 16,  6,  6, 21],
    [16, 16,  6, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21]
  ],
  // TX_16X64
  [
    [ 0, 11, 11, 11, 11],
    [11, 11, 11, 11, 11],
    [ 6,  6, 21, 21, 21],
    [ 6, 21, 21, 21, 21],
    [21, 21, 21, 21, 21]
  ],
  // TX_64X16
  [
    [ 0, 16,  6,  6, 21],
    [16, 16,  6, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21],
    [16, 16, 21, 21, 21]
  ]
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
];

const NZ_MAP_CTX_0: usize = SIG_COEF_CONTEXTS_2D;
const NZ_MAP_CTX_5: usize = (NZ_MAP_CTX_0 + 5);
const NZ_MAP_CTX_10: usize = (NZ_MAP_CTX_0 + 10);

static nz_map_ctx_offset_1d: [usize; 32] = [
  NZ_MAP_CTX_0,  NZ_MAP_CTX_5,  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
  NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10, NZ_MAP_CTX_10,
  NZ_MAP_CTX_10, NZ_MAP_CTX_10 ];

const CONTEXT_MAG_POSITION_NUM: usize = 3;

static mag_ref_offset_with_txclass: [[[usize; 2]; CONTEXT_MAG_POSITION_NUM]; 3] = [
  [ [ 0, 1 ], [ 1, 0 ], [ 1, 1 ] ],
  [ [ 0, 1 ], [ 1, 0 ], [ 0, 2 ] ],
  [ [ 0, 1 ], [ 1, 0 ], [ 2, 0 ] ] ];

// End of Level Map

Michael Bebenita's avatar
Michael Bebenita committed
558
pub fn has_chroma(
Romain Vimont's avatar
Romain Vimont committed
559
  bo: BlockOffset, bsize: BlockSize, subsampling_x: usize,
Michael Bebenita's avatar
Michael Bebenita committed
560
561
562
563
  subsampling_y: usize
) -> bool {
  let bw = bsize.width_mi();
  let bh = bsize.height_mi();
Yushin Cho's avatar
Yushin Cho committed
564

Michael Bebenita's avatar
Michael Bebenita committed
565
566
  ((bo.x & 0x01) == 1 || (bw & 0x01) == 0 || subsampling_x == 0)
    && ((bo.y & 0x01) == 1 || (bh & 0x01) == 0 || subsampling_y == 0)
Yushin Cho's avatar
Yushin Cho committed
567
568
}

Yushin Cho's avatar
Yushin Cho committed
569
pub fn get_tx_set(
Michael Bebenita's avatar
Michael Bebenita committed
570
  tx_size: TxSize, is_inter: bool, use_reduced_set: bool
Yushin Cho's avatar
Yushin Cho committed
571
) -> TxSet {
572
  let tx_size_sqr_up = tx_size.sqr_up();
Michael Bebenita's avatar
Michael Bebenita committed
573
  let tx_size_sqr = tx_size.sqr();
574
575

  if tx_size.width() >= 64 || tx_size.height() >= 64 {
576
577
578
579
580
    return TxSet::TX_SET_DCTONLY;
  }

  if tx_size_sqr_up == TxSize::TX_32X32 {
    return if is_inter {
Yushin Cho's avatar
Yushin Cho committed
581
      TxSet::TX_SET_DCT_IDTX
582
    } else {
Yushin Cho's avatar
Yushin Cho committed
583
      TxSet::TX_SET_DCTONLY
584
585
586
587
588
    };
  }

  if use_reduced_set {
    return if is_inter {
Yushin Cho's avatar
Yushin Cho committed
589
      TxSet::TX_SET_DCT_IDTX
Michael Bebenita's avatar
Michael Bebenita committed
590
    } else {
Yushin Cho's avatar
Yushin Cho committed
591
      TxSet::TX_SET_DTT4_IDTX
592
593
594
595
596
    };
  }

  if is_inter {
    return if tx_size_sqr == TxSize::TX_16X16 {
Yushin Cho's avatar
Yushin Cho committed
597
      TxSet::TX_SET_DTT9_IDTX_1DDCT
Thomas Daede's avatar
Thomas Daede committed
598
    } else {
Yushin Cho's avatar
Yushin Cho committed
599
      TxSet::TX_SET_ALL16
600
601
602
603
604
    };
  }

  if tx_size_sqr == TxSize::TX_16X16 {
    TxSet::TX_SET_DTT4_IDTX
Michael Bebenita's avatar
Michael Bebenita committed
605
  } else {
606
    TxSet::TX_SET_DTT4_IDTX_1DDCT
Michael Bebenita's avatar
Michael Bebenita committed
607
608
609
  }
}

Yushin Cho's avatar
Yushin Cho committed
610
fn get_tx_set_index(
Michael Bebenita's avatar
Michael Bebenita committed
611
612
  tx_size: TxSize, is_inter: bool, use_reduced_set: bool
) -> i8 {
Yushin Cho's avatar
Yushin Cho committed
613
  let set_type = get_tx_set(tx_size, is_inter, use_reduced_set);
Michael Bebenita's avatar
Michael Bebenita committed
614
615

  if is_inter {
Yushin Cho's avatar
Yushin Cho committed
616
    tx_set_index_inter[set_type as usize]
Michael Bebenita's avatar
Michael Bebenita committed
617
  } else {
Yushin Cho's avatar
Yushin Cho committed
618
    tx_set_index_intra[set_type as usize]
Michael Bebenita's avatar
Michael Bebenita committed
619
  }
Thomas Daede's avatar
Thomas Daede committed
620
621
}

Thomas Daede's avatar
Thomas Daede committed
622
static intra_mode_to_tx_type_context: [TxType; INTRA_MODES] = [
Michael Bebenita's avatar
Michael Bebenita committed
623
624
625
626
627
628
629
630
631
632
633
634
635
  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, // SMOOTH
  ADST_DCT,  // SMOOTH_V
  DCT_ADST,  // SMOOTH_H
  ADST_ADST, // PAETH
Thomas Daede's avatar
Thomas Daede committed
636
637
];

638

Thomas Daede's avatar
Thomas Daede committed
639
static uv2y: [PredictionMode; UV_INTRA_MODES] = [
Michael Bebenita's avatar
Michael Bebenita committed
640
641
642
643
644
645
646
647
648
649
650
651
652
653
  DC_PRED,       // UV_DC_PRED
  V_PRED,        // UV_V_PRED
  H_PRED,        // UV_H_PRED
  D45_PRED,      // UV_D45_PRED
  D135_PRED,     // UV_D135_PRED
  D117_PRED,     // UV_D117_PRED
  D153_PRED,     // UV_D153_PRED
  D207_PRED,     // UV_D207_PRED
  D63_PRED,      // UV_D63_PRED
  SMOOTH_PRED,   // UV_SMOOTH_PRED
  SMOOTH_V_PRED, // UV_SMOOTH_V_PRED
  SMOOTH_H_PRED, // UV_SMOOTH_H_PRED
  PAETH_PRED,    // UV_PAETH_PRED
  DC_PRED        // CFL_PRED
Thomas Daede's avatar
Thomas Daede committed
654
655
];

Michael Bebenita's avatar
Michael Bebenita committed
656
657
pub fn uv_intra_mode_to_tx_type_context(pred: PredictionMode) -> TxType {
  intra_mode_to_tx_type_context[uv2y[pred as usize] as usize]
Thomas Daede's avatar
Thomas Daede committed
658
659
}

660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
#[derive(Clone,Copy)]
pub struct NMVComponent {
  classes_cdf: [u16; MV_CLASSES + 1],
  class0_fp_cdf: [[u16; MV_FP_SIZE + 1]; CLASS0_SIZE],
  fp_cdf: [u16; MV_FP_SIZE + 1],
  sign_cdf: [u16; 2 + 1],
  class0_hp_cdf: [u16; 2 + 1],
  hp_cdf: [u16; 2 + 1],
  class0_cdf: [u16; CLASS0_SIZE + 1],
  bits_cdf: [[u16; 2 + 1]; MV_OFFSET_BITS],
}

#[derive(Clone,Copy)]
pub struct NMVContext {
  joints_cdf: [u16; MV_JOINTS + 1],
  comps: [NMVComponent; 2],
}

Thomas Daede's avatar
Thomas Daede committed
678
extern "C" {
tmpcnt's avatar
tmpcnt committed
679
  //static av1_scan_orders: [[SCAN_ORDER; TX_TYPES]; TxSize::TX_SIZES_ALL];
Guillaume Martres's avatar
Guillaume Martres committed
680
681
}

SmilingWolf's avatar
SmilingWolf committed
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
// lv_map
static default_nmv_context: NMVContext = {
  NMVContext {
    joints_cdf: cdf!(4096, 11264, 19328),
    comps: [
      NMVComponent {
        classes_cdf: cdf!(
          28672, 30976, 31858, 32320, 32551, 32656, 32740, 32757, 32762, 32767
        ),
        class0_fp_cdf: [cdf!(16384, 24576, 26624), cdf!(12288, 21248, 24128)],
        fp_cdf: cdf!(8192, 17408, 21248),
        sign_cdf: cdf!(128 * 128),
        class0_hp_cdf: cdf!(160 * 128),
        hp_cdf: cdf!(128 * 128),
        class0_cdf: cdf!(216 * 128),
        bits_cdf: [
          cdf!(128 * 136),
          cdf!(128 * 140),
          cdf!(128 * 148),
          cdf!(128 * 160),
          cdf!(128 * 176),
          cdf!(128 * 192),
          cdf!(128 * 224),
          cdf!(128 * 234),
          cdf!(128 * 234),
          cdf!(128 * 240)
        ]
      },
      NMVComponent {
        classes_cdf: cdf!(
          28672, 30976, 31858, 32320, 32551, 32656, 32740, 32757, 32762, 32767
        ),
        class0_fp_cdf: [cdf!(16384, 24576, 26624), cdf!(12288, 21248, 24128)],
        fp_cdf: cdf!(8192, 17408, 21248),
        sign_cdf: cdf!(128 * 128),
        class0_hp_cdf: cdf!(160 * 128),
        hp_cdf: cdf!(128 * 128),
        class0_cdf: cdf!(216 * 128),
        bits_cdf: [
          cdf!(128 * 136),
          cdf!(128 * 140),
          cdf!(128 * 148),
          cdf!(128 * 160),
          cdf!(128 * 176),
          cdf!(128 * 192),
          cdf!(128 * 224),
          cdf!(128 * 234),
          cdf!(128 * 234),
          cdf!(128 * 240)
        ]
      }
    ]
  }
};

737
738
739
740
741
742
743
#[derive(Clone)]
pub struct CandidateMV {
  pub this_mv: MotionVector,
  pub comp_mv: MotionVector,
  pub weight: u32
}

744
#[derive(Clone,Copy)]
Thomas Daede's avatar
Thomas Daede committed
745
pub struct CDFContext {
Thomas Daede's avatar
Thomas Daede committed
746
  partition_cdf: [[u16; EXT_PARTITION_TYPES + 1]; PARTITION_CONTEXTS],
Michael Bebenita's avatar
Michael Bebenita committed
747
748
749
  kf_y_cdf: [[[u16; INTRA_MODES + 1]; KF_MODE_CONTEXTS]; KF_MODE_CONTEXTS],
  y_mode_cdf: [[u16; INTRA_MODES + 1]; BLOCK_SIZE_GROUPS],
  uv_mode_cdf: [[[u16; UV_INTRA_MODES + 1]; INTRA_MODES]; 2],
750
751
  cfl_sign_cdf: [u16; CFL_JOINT_SIGNS + 1],
  cfl_alpha_cdf: [[u16; CFL_ALPHABET_SIZE + 1]; CFL_ALPHA_CONTEXTS],
752
753
754
  newmv_cdf: [[u16; 2 + 1]; NEWMV_MODE_CONTEXTS],
  zeromv_cdf: [[u16; 2 + 1]; GLOBALMV_MODE_CONTEXTS],
  refmv_cdf: [[u16; 2 + 1]; REFMV_MODE_CONTEXTS],
Yushin Cho's avatar
Yushin Cho committed
755
  intra_tx_cdf:
756
757
    [[[[u16; TX_TYPES + 1]; INTRA_MODES]; TX_SIZE_SQR_CONTEXTS]; TX_SETS_INTRA],
  inter_tx_cdf: [[[u16; TX_TYPES + 1]; TX_SIZE_SQR_CONTEXTS]; TX_SETS_INTER],
758
  tx_size_cdf: [[[u16; MAX_TX_DEPTH + 1 + 1]; TX_SIZE_CONTEXTS]; MAX_TX_CATS],
Michael Bebenita's avatar
Michael Bebenita committed
759
760
761
  skip_cdfs: [[u16; 3]; SKIP_CONTEXTS],
  intra_inter_cdfs: [[u16; 3]; INTRA_INTER_CONTEXTS],
  angle_delta_cdf: [[u16; 2 * MAX_ANGLE_DELTA + 1 + 1]; DIRECTIONAL_MODES],
Thomas Daede's avatar
Thomas Daede committed
762
  filter_intra_cdfs: [[u16; 3]; BlockSize::BLOCK_SIZES_ALL],
fbossen's avatar
fbossen committed
763
764
765
766
  comp_mode_cdf: [[u16; 3]; COMP_INTER_CONTEXTS],
  comp_ref_type_cdf: [[u16; 3]; COMP_REF_TYPE_CONTEXTS],
  comp_ref_cdf: [[[u16; 3]; FWD_REFS - 1]; REF_CONTEXTS],
  comp_bwd_ref_cdf: [[[u16; 3]; BWD_REFS - 1]; REF_CONTEXTS],
767
  single_ref_cdfs: [[[u16; 2 + 1]; SINGLE_REFS - 1]; REF_CONTEXTS],
768
  drl_cdfs: [[u16; 2 + 1]; DRL_MODE_CONTEXTS],
fbossen's avatar
fbossen committed
769
  compound_mode_cdf: [[u16; INTER_COMPOUND_MODES + 1]; INTER_MODE_CONTEXTS],
770
  nmv_context: NMVContext,
771
772
  deblock_delta_multi_cdf: [[u16; DELTA_LF_PROBS + 1 + 1]; FRAME_LF_COUNT],
  deblock_delta_cdf: [u16; DELTA_LF_PROBS + 1 + 1],
773
  spatial_segmentation_cdfs: [[u16; 8 + 1]; 3],
774
775
776
  lrf_switchable_cdf: [u16; 3+1],
  lrf_sgrproj_cdf: [u16; 2+1],
  lrf_wiener_cdf: [u16; 2+1],
Michael Bebenita's avatar
Michael Bebenita committed
777
778
779

  // lv_map
  txb_skip_cdf: [[[u16; 3]; TXB_SKIP_CONTEXTS]; TxSize::TX_SIZES],
Thomas Daede's avatar
Thomas Daede committed
780
  dc_sign_cdf: [[[u16; 3]; DC_SIGN_CONTEXTS]; PLANE_TYPES],
Michael Bebenita's avatar
Michael Bebenita committed
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
  eob_extra_cdf:
    [[[[u16; 3]; EOB_COEF_CONTEXTS]; PLANE_TYPES]; TxSize::TX_SIZES],

  eob_flag_cdf16: [[[u16; 5 + 1]; 2]; PLANE_TYPES],
  eob_flag_cdf32: [[[u16; 6 + 1]; 2]; PLANE_TYPES],
  eob_flag_cdf64: [[[u16; 7 + 1]; 2]; PLANE_TYPES],
  eob_flag_cdf128: [[[u16; 8 + 1]; 2]; PLANE_TYPES],
  eob_flag_cdf256: [[[u16; 9 + 1]; 2]; PLANE_TYPES],
  eob_flag_cdf512: [[[u16; 10 + 1]; 2]; PLANE_TYPES],
  eob_flag_cdf1024: [[[u16; 11 + 1]; 2]; PLANE_TYPES],

  coeff_base_eob_cdf:
    [[[[u16; 3 + 1]; SIG_COEF_CONTEXTS_EOB]; PLANE_TYPES]; TxSize::TX_SIZES],
  coeff_base_cdf:
    [[[[u16; 4 + 1]; SIG_COEF_CONTEXTS]; PLANE_TYPES]; TxSize::TX_SIZES],
  coeff_br_cdf: [[[[u16; BR_CDF_SIZE + 1]; LEVEL_CONTEXTS]; PLANE_TYPES];
    TxSize::TX_SIZES]
Thomas Daede's avatar
Thomas Daede committed
798
799
800
}

impl CDFContext {
801
802
    pub fn new(quantizer: u8) -> CDFContext {
    let qctx = match quantizer {
gibix's avatar
gibix committed
803
804
805
      0..=20 => 0,
      21..=60 => 1,
      61..=120 => 2,
Thomas Daede's avatar
Thomas Daede committed
806
807
      _ => 3
    };
Michael Bebenita's avatar
Michael Bebenita committed
808
    CDFContext {
Michael Bebenita's avatar
Michael Bebenita committed
809
810
811
812
      partition_cdf: default_partition_cdf,
      kf_y_cdf: default_kf_y_mode_cdf,
      y_mode_cdf: default_if_y_mode_cdf,
      uv_mode_cdf: default_uv_mode_cdf,
813
814
      cfl_sign_cdf: default_cfl_sign_cdf,
      cfl_alpha_cdf: default_cfl_alpha_cdf,
815
816
817
      newmv_cdf: default_newmv_cdf,
      zeromv_cdf: default_zeromv_cdf,
      refmv_cdf: default_refmv_cdf,
Yushin Cho's avatar
Yushin Cho committed
818
819
      intra_tx_cdf: default_intra_ext_tx_cdf,
      inter_tx_cdf: default_inter_ext_tx_cdf,
820
      tx_size_cdf: default_tx_size_cdf,
Michael Bebenita's avatar
Michael Bebenita committed
821
822
823
      skip_cdfs: default_skip_cdfs,
      intra_inter_cdfs: default_intra_inter_cdf,
      angle_delta_cdf: default_angle_delta_cdf,
824
      filter_intra_cdfs: default_filter_intra_cdfs,
fbossen's avatar
fbossen committed
825
826
827
828
      comp_mode_cdf: default_comp_mode_cdf,
      comp_ref_type_cdf: default_comp_ref_type_cdf,
      comp_ref_cdf: default_comp_ref_cdf,
      comp_bwd_ref_cdf: default_comp_bwdref_cdf,
829
      single_ref_cdfs: default_single_ref_cdf,
830
      drl_cdfs: default_drl_cdf,
fbossen's avatar
fbossen committed
831
      compound_mode_cdf: default_compound_mode_cdf,
832
      nmv_context: default_nmv_context,
833
834
      deblock_delta_multi_cdf: default_delta_lf_multi_cdf,
      deblock_delta_cdf: default_delta_lf_cdf,
835
      spatial_segmentation_cdfs: default_spatial_pred_seg_tree_cdf,
836
837
838
      lrf_switchable_cdf: default_switchable_restore_cdf,
      lrf_sgrproj_cdf: default_sgrproj_restore_cdf,
      lrf_wiener_cdf: default_wiener_restore_cdf,
Michael Bebenita's avatar
Michael Bebenita committed
839
840

      // lv_map
Thomas Daede's avatar
Thomas Daede committed
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
      txb_skip_cdf: av1_default_txb_skip_cdfs[qctx],
      dc_sign_cdf: av1_default_dc_sign_cdfs[qctx],
      eob_extra_cdf: av1_default_eob_extra_cdfs[qctx],

      eob_flag_cdf16: av1_default_eob_multi16_cdfs[qctx],
      eob_flag_cdf32: av1_default_eob_multi32_cdfs[qctx],
      eob_flag_cdf64: av1_default_eob_multi64_cdfs[qctx],
      eob_flag_cdf128: av1_default_eob_multi128_cdfs[qctx],
      eob_flag_cdf256: av1_default_eob_multi256_cdfs[qctx],
      eob_flag_cdf512: av1_default_eob_multi512_cdfs[qctx],
      eob_flag_cdf1024: av1_default_eob_multi1024_cdfs[qctx],

      coeff_base_eob_cdf: av1_default_coeff_base_eob_multi_cdfs[qctx],
      coeff_base_cdf: av1_default_coeff_base_multi_cdfs[qctx],
      coeff_br_cdf: av1_default_coeff_lps_multi_cdfs[qctx]
Michael Bebenita's avatar
Michael Bebenita committed
856
    }
Michael Bebenita's avatar
Michael Bebenita committed
857
858
  }

859
860
861
862
863
  pub fn reset_counts(&mut self) {
    macro_rules! reset_1d {
      ($field:expr) => (let r = $field.last_mut().unwrap(); *r = 0;)
    }
    macro_rules! reset_2d {
Raphaël Zumer's avatar
Raphaël Zumer committed
864
      ($field:expr) => (for x in $field.iter_mut() { reset_1d!(x); })
865
866
    }
    macro_rules! reset_3d {
Raphaël Zumer's avatar
Raphaël Zumer committed
867
      ($field:expr) => (for x in $field.iter_mut() { reset_2d!(x); })
868
869
    }
    macro_rules! reset_4d {
Raphaël Zumer's avatar
Raphaël Zumer committed
870
      ($field:expr) => (for x in $field.iter_mut() { reset_3d!(x); })
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
    }

    for i in 0..4 { self.partition_cdf[i][4] = 0; }
    for i in 4..16 { self.partition_cdf[i][10] = 0; }
    for i in 16..20 { self.partition_cdf[i][8] = 0; }

    reset_3d!(self.kf_y_cdf);
    reset_2d!(self.y_mode_cdf);

    for i in 0..INTRA_MODES {
      self.uv_mode_cdf[0][i][UV_INTRA_MODES - 1] = 0;
      self.uv_mode_cdf[1][i][UV_INTRA_MODES] = 0;
    }
    reset_1d!(self.cfl_sign_cdf);
    reset_2d!(self.cfl_alpha_cdf);
    reset_2d!(self.newmv_cdf);
    reset_2d!(self.zeromv_cdf);
    reset_2d!(self.refmv_cdf);

890
    for i in 0..TX_SIZE_SQR_CONTEXTS {
891
892
893
894
895
896
897
898
899
      for j in 0..INTRA_MODES {
        self.intra_tx_cdf[1][i][j][7] = 0;
        self.intra_tx_cdf[2][i][j][5] = 0;
      }
      self.inter_tx_cdf[1][i][16] = 0;
      self.inter_tx_cdf[2][i][12] = 0;
      self.inter_tx_cdf[3][i][2] = 0;
    }

900
901
902
903
904
    for i in 0..TX_SIZE_CONTEXTS { self.tx_size_cdf[0][i][MAX_TX_DEPTH] = 0; }
    reset_2d!(self.tx_size_cdf[1]);
    reset_2d!(self.tx_size_cdf[2]);
    reset_2d!(self.tx_size_cdf[3]);

905
906
907
908
    reset_2d!(self.skip_cdfs);
    reset_2d!(self.intra_inter_cdfs);
    reset_2d!(self.angle_delta_cdf);
    reset_2d!(self.filter_intra_cdfs);
fbossen's avatar
fbossen committed
909
910
911
912
    reset_2d!(self.comp_mode_cdf);
    reset_2d!(self.comp_ref_type_cdf);
    reset_3d!(self.comp_ref_cdf);
    reset_3d!(self.comp_bwd_ref_cdf);
913
914
    reset_3d!(self.single_ref_cdfs);
    reset_2d!(self.drl_cdfs);
fbossen's avatar
fbossen committed
915
    reset_2d!(self.compound_mode_cdf);
916
917
    reset_2d!(self.deblock_delta_multi_cdf);
    reset_1d!(self.deblock_delta_cdf);
918
    reset_2d!(self.spatial_segmentation_cdfs);
919
920
921
    reset_1d!(self.lrf_switchable_cdf);
    reset_1d!(self.lrf_sgrproj_cdf);
    reset_1d!(self.lrf_wiener_cdf);
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952

    reset_1d!(self.nmv_context.joints_cdf);
    for i in 0..2 {
      reset_1d!(self.nmv_context.comps[i].classes_cdf);
      reset_2d!(self.nmv_context.comps[i].class0_fp_cdf);
      reset_1d!(self.nmv_context.comps[i].fp_cdf);
      reset_1d!(self.nmv_context.comps[i].sign_cdf);
      reset_1d!(self.nmv_context.comps[i].class0_hp_cdf);
      reset_1d!(self.nmv_context.comps[i].hp_cdf);
      reset_1d!(self.nmv_context.comps[i].class0_cdf);
      reset_2d!(self.nmv_context.comps[i].bits_cdf);
    }

    // lv_map
    reset_3d!(self.txb_skip_cdf);
    reset_3d!(self.dc_sign_cdf);
    reset_4d!(self.eob_extra_cdf);

    reset_3d!(self.eob_flag_cdf16);
    reset_3d!(self.eob_flag_cdf32);
    reset_3d!(self.eob_flag_cdf64);
    reset_3d!(self.eob_flag_cdf128);
    reset_3d!(self.eob_flag_cdf256);
    reset_3d!(self.eob_flag_cdf512);
    reset_3d!(self.eob_flag_cdf1024);

    reset_4d!(self.coeff_base_eob_cdf);
    reset_4d!(self.coeff_base_cdf);
    reset_4d!(self.coeff_br_cdf);
  }

Michael Bebenita's avatar
Michael Bebenita committed
953
954
955
956
957
958
959
960
961
962
963
964
965
966
  pub fn build_map(&self) -> Vec<(&'static str, usize, usize)> {
    use std::mem::size_of_val;

    let partition_cdf_start =
      self.partition_cdf.first().unwrap().as_ptr() as usize;
    let partition_cdf_end =
      partition_cdf_start + size_of_val(&self.partition_cdf);
    let kf_y_cdf_start = self.kf_y_cdf.first().unwrap().as_ptr() as usize;
    let kf_y_cdf_end = kf_y_cdf_start + size_of_val(&self.kf_y_cdf);
    let y_mode_cdf_start = self.y_mode_cdf.first().unwrap().as_ptr() as usize;
    let y_mode_cdf_end = y_mode_cdf_start + size_of_val(&self.y_mode_cdf);
    let uv_mode_cdf_start =
      self.uv_mode_cdf.first().unwrap().as_ptr() as usize;
    let uv_mode_cdf_end = uv_mode_cdf_start + size_of_val(&self.uv_mode_cdf);
967
968
969
970
971
972
    let cfl_sign_cdf_start = self.cfl_sign_cdf.as_ptr() as usize;
    let cfl_sign_cdf_end = cfl_sign_cdf_start + size_of_val(&self.cfl_sign_cdf);
    let cfl_alpha_cdf_start =
      self.cfl_alpha_cdf.first().unwrap().as_ptr() as usize;
    let cfl_alpha_cdf_end =
      cfl_alpha_cdf_start + size_of_val(&self.cfl_alpha_cdf);
Yushin Cho's avatar
Yushin Cho committed
973
974
975
976
977
978
979
980
    let intra_tx_cdf_start =
      self.intra_tx_cdf.first().unwrap().as_ptr() as usize;
    let intra_tx_cdf_end =
      intra_tx_cdf_start + size_of_val(&self.intra_tx_cdf);
    let inter_tx_cdf_start =
      self.inter_tx_cdf.first().unwrap().as_ptr() as usize;
    let inter_tx_cdf_end =
      inter_tx_cdf_start + size_of_val(&self.inter_tx_cdf);
Michael Bebenita's avatar
Michael Bebenita committed
981
982
983
984
985
986
987
988
989
990
    let skip_cdfs_start = self.skip_cdfs.first().unwrap().as_ptr() as usize;
    let skip_cdfs_end = skip_cdfs_start + size_of_val(&self.skip_cdfs);
    let intra_inter_cdfs_start =
      self.intra_inter_cdfs.first().unwrap().as_ptr() as usize;
    let intra_inter_cdfs_end =
      intra_inter_cdfs_start + size_of_val(&self.intra_inter_cdfs);
    let angle_delta_cdf_start =
      self.angle_delta_cdf.first().unwrap().as_ptr() as usize;
    let angle_delta_cdf_end =
      angle_delta_cdf_start + size_of_val(&self.angle_delta_cdf);
991
992
993
994
    let filter_intra_cdfs_start =
      self.filter_intra_cdfs.first().unwrap().as_ptr() as usize;
    let filter_intra_cdfs_end =
      filter_intra_cdfs_start + size_of_val(&self.filter_intra_cdfs);
fbossen's avatar
fbossen committed
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
    let comp_mode_cdf_start =
      self.comp_mode_cdf.first().unwrap().as_ptr() as usize;
    let comp_mode_cdf_end =
      comp_mode_cdf_start + size_of_val(&self.comp_mode_cdf);
    let comp_ref_type_cdf_start =
      self.comp_ref_type_cdf.first().unwrap().as_ptr() as usize;
    let comp_ref_type_cdf_end =
      comp_ref_type_cdf_start + size_of_val(&self.comp_ref_type_cdf);
    let comp_ref_cdf_start =
      self.comp_ref_cdf.first().unwrap().as_ptr() as usize;
    let comp_ref_cdf_end =
      comp_ref_cdf_start + size_of_val(&self.comp_ref_cdf);
    let comp_bwd_ref_cdf_start =
      self.comp_bwd_ref_cdf.first().unwrap().as_ptr() as usize;
    let comp_bwd_ref_cdf_end =
      comp_bwd_ref_cdf_start + size_of_val(&self.comp_bwd_ref_cdf);
1011
1012
1013
1014
1015
1016
1017
1018
    let deblock_delta_multi_cdf_start =
      self.deblock_delta_multi_cdf.first().unwrap().as_ptr() as usize;
    let deblock_delta_multi_cdf_end =
      deblock_delta_multi_cdf_start + size_of_val(&self.deblock_delta_multi_cdf);
    let deblock_delta_cdf_start =
      self.deblock_delta_cdf.as_ptr() as usize;
    let deblock_delta_cdf_end =
      deblock_delta_cdf_start + size_of_val(&self.deblock_delta_cdf);
1019
1020
1021
1022
    let spatial_segmentation_cdfs_start =
      self.spatial_segmentation_cdfs.first().unwrap().as_ptr() as usize;
    let spatial_segmentation_cdfs_end =
      spatial_segmentation_cdfs_start + size_of_val(&self.spatial_segmentation_cdfs);
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
    let lrf_switchable_cdf_start =
      self.lrf_switchable_cdf.as_ptr() as usize;
    let lrf_switchable_cdf_end =
      lrf_switchable_cdf_start + size_of_val(&self.lrf_switchable_cdf);
    let lrf_sgrproj_cdf_start =
      self.lrf_sgrproj_cdf.as_ptr() as usize;
    let lrf_sgrproj_cdf_end =
      lrf_sgrproj_cdf_start + size_of_val(&self.lrf_sgrproj_cdf);
    let lrf_wiener_cdf_start =
      self.lrf_wiener_cdf.as_ptr() as usize;
    let lrf_wiener_cdf_end =
      lrf_wiener_cdf_start + size_of_val(&self.lrf_wiener_cdf);
1035

Michael Bebenita's avatar
Michael Bebenita committed
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
    let txb_skip_cdf_start =
      self.txb_skip_cdf.first().unwrap().as_ptr() as usize;
    let txb_skip_cdf_end =
      txb_skip_cdf_start + size_of_val(&self.txb_skip_cdf);
    let dc_sign_cdf_start =
      self.dc_sign_cdf.first().unwrap().as_ptr() as usize;
    let dc_sign_cdf_end = dc_sign_cdf_start + size_of_val(&self.dc_sign_cdf);
    let eob_extra_cdf_start =
      self.eob_extra_cdf.first().unwrap().as_ptr() as usize;
    let eob_extra_cdf_end =
      eob_extra_cdf_start + size_of_val(&self.eob_extra_cdf);
    let eob_flag_cdf16_start =
      self.eob_flag_cdf16.first().unwrap().as_ptr() as usize;
    let eob_flag_cdf16_end =
      eob_flag_cdf16_start + size_of_val(&self.eob_flag_cdf16);
    let eob_flag_cdf32_start =
      self.eob_flag_cdf32.first().unwrap().as_ptr() as usize;
    let eob_flag_cdf32_end =
      eob_flag_cdf32_start + size_of_val(&self.eob_flag_cdf32);
    let eob_flag_cdf64_start =
      self.eob_flag_cdf64.first().unwrap().as_ptr() as usize;
    let eob_flag_cdf64_end =
      eob_flag_cdf64_start + size_of_val(&self.eob_flag_cdf64);
    let eob_flag_cdf128_start =
      self.eob_flag_cdf128.first().unwrap().as_ptr() as usize;
    let eob_flag_cdf128_end =
      eob_flag_cdf128_start + size_of_val(&self.eob_flag_cdf128);
    let eob_flag_cdf256_start =
      self.eob_flag_cdf256.first().unwrap().as_ptr() as usize;
    let eob_flag_cdf256_end =
      eob_flag_cdf256_start + size_of_val(&self.eob_flag_cdf256);
    let eob_flag_cdf512_start =
      self.eob_flag_cdf512.first().unwrap().as_ptr() as usize;
    let eob_flag_cdf512_end =
      eob_flag_cdf512_start + size_of_val(&self.eob_flag_cdf512);
    let eob_flag_cdf1024_start =
      self.eob_flag_cdf1024.first().unwrap().as_ptr() as usize;
    let eob_flag_cdf1024_end =
      eob_flag_cdf1024_start + size_of_val(&self.eob_flag_cdf1024);
    let coeff_base_eob_cdf_start =
      self.coeff_base_eob_cdf.first().unwrap().as_ptr() as usize;
    let coeff_base_eob_cdf_end =
      coeff_base_eob_cdf_start + size_of_val(&self.coeff_base_eob_cdf);
    let coeff_base_cdf_start =
      self.coeff_base_cdf.first().unwrap().as_ptr() as usize;
    let coeff_base_cdf_end =
      coeff_base_cdf_start + size_of_val(&self.coeff_base_cdf);
    let coeff_br_cdf_start =
      self.coeff_br_cdf.first().unwrap().as_ptr() as usize;
    let coeff_br_cdf_end =
      coeff_br_cdf_start + size_of_val(&self.coeff_br_cdf);

    vec![
      ("partition_cdf", partition_cdf_start, partition_cdf_end),
      ("kf_y_cdf", kf_y_cdf_start, kf_y_cdf_end),
      ("y_mode_cdf", y_mode_cdf_start, y_mode_cdf_end),
      ("uv_mode_cdf", uv_mode_cdf_start, uv_mode_cdf_end),
1093
1094
      ("cfl_sign_cdf", cfl_sign_cdf_start, cfl_sign_cdf_end),
      ("cfl_alpha_cdf", cfl_alpha_cdf_start, cfl_alpha_cdf_end),
Yushin Cho's avatar
Yushin Cho committed
1095
1096
      ("intra_tx_cdf", intra_tx_cdf_start, intra_tx_cdf_end),
      ("inter_tx_cdf", inter_tx_cdf_start, inter_tx_cdf_end),
Michael Bebenita's avatar
Michael Bebenita committed
1097
1098
1099
      ("skip_cdfs", skip_cdfs_start, skip_cdfs_end),
      ("intra_inter_cdfs", intra_inter_cdfs_start, intra_inter_cdfs_end),
      ("angle_delta_cdf", angle_delta_cdf_start, angle_delta_cdf_end),
1100
      ("filter_intra_cdfs", filter_intra_cdfs_start, filter_intra_cdfs_end),
fbossen's avatar
fbossen committed
1101
1102
1103
1104
      ("comp_mode_cdf", comp_mode_cdf_start, comp_mode_cdf_end),
      ("comp_ref_type_cdf", comp_ref_type_cdf_start, comp_ref_type_cdf_end),
      ("comp_ref_cdf", comp_ref_cdf_start, comp_ref_cdf_end),
      ("comp_bwd_ref_cdf", comp_bwd_ref_cdf_start, comp_bwd_ref_cdf_end),
1105
1106
      ("deblock_delta_multi_cdf", deblock_delta_multi_cdf_start, deblock_delta_multi_cdf_end),
      ("deblock_delta_cdf", deblock_delta_cdf_start, deblock_delta_cdf_end),
1107
      ("spatial_segmentation_cdfs", spatial_segmentation_cdfs_start, spatial_segmentation_cdfs_end),
1108
1109
1110
      ("lrf_switchable_cdf", lrf_switchable_cdf_start, lrf_switchable_cdf_end),
      ("lrf_sgrproj_cdf", lrf_sgrproj_cdf_start, lrf_sgrproj_cdf_end),
      ("lrf_wiener_cdf", lrf_wiener_cdf_start, lrf_wiener_cdf_end),
Michael Bebenita's avatar
Michael Bebenita committed
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
      ("txb_skip_cdf", txb_skip_cdf_start, txb_skip_cdf_end),
      ("dc_sign_cdf", dc_sign_cdf_start, dc_sign_cdf_end),
      ("eob_extra_cdf", eob_extra_cdf_start, eob_extra_cdf_end),
      ("eob_flag_cdf16", eob_flag_cdf16_start, eob_flag_cdf16_end),
      ("eob_flag_cdf32", eob_flag_cdf32_start, eob_flag_cdf32_end),
      ("eob_flag_cdf64", eob_flag_cdf64_start, eob_flag_cdf64_end),
      ("eob_flag_cdf128", eob_flag_cdf128_start, eob_flag_cdf128_end),
      ("eob_flag_cdf256", eob_flag_cdf256_start, eob_flag_cdf256_end),
      ("eob_flag_cdf512", eob_flag_cdf512_start, eob_flag_cdf512_end),
      ("eob_flag_cdf1024", eob_flag_cdf1024_start, eob_flag_cdf1024_end),
      ("coeff_base_eob_cdf", coeff_base_eob_cdf_start, coeff_base_eob_cdf_end),
      ("coeff_base_cdf", coeff_base_cdf_start, coeff_base_cdf_end),
      ("coeff_br_cdf", coeff_br_cdf_start, coeff_br_cdf_end),
    ]
  }
1126
1127
}

1128
impl fmt::Debug for CDFContext {
1129
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1130
1131
1132
1133
    write!(f, "CDFContext contains too many numbers to print :-(")
  }
}

1134
1135
#[cfg(test)]
mod test {
Michael Bebenita's avatar
Michael Bebenita committed
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
  #[test]
  fn cdf_map() {
    use super::*;

    let cdf = CDFContext::new(8);
    let cdf_map = FieldMap {
      map: cdf.build_map()
    };
    let f = &cdf.partition_cdf[2];
    cdf_map.lookup(f.as_ptr() as usize);
  }
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170

  use super::CFLSign;
  use super::CFLSign::*;

  static cfl_alpha_signs: [[CFLSign; 2]; 8] = [
    [ CFL_SIGN_ZERO, CFL_SIGN_NEG ],
    [ CFL_SIGN_ZERO, CFL_SIGN_POS ],
    [ CFL_SIGN_NEG, CFL_SIGN_ZERO ],
    [ CFL_SIGN_NEG, CFL_SIGN_NEG ],
    [ CFL_SIGN_NEG, CFL_SIGN_POS ],
    [ CFL_SIGN_POS, CFL_SIGN_ZERO ],
    [ CFL_SIGN_POS, CFL_SIGN_NEG ],
    [ CFL_SIGN_POS, CFL_SIGN_POS ]
  ];

  static cfl_context: [[usize; 8]; 2] = [
    [ 0, 0, 0, 1, 2, 3, 4, 5 ],
    [ 0, 3, 0, 1, 4, 0, 2, 5 ]
  ];

  #[test]
  fn cfl_joint_sign() {
    use super::*;

1171
    let mut cfl = CFLParams::default();
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
    for (joint_sign, &signs) in cfl_alpha_signs.iter().enumerate() {
      cfl.sign = signs;
      assert!(cfl.joint_sign() as usize == joint_sign);
      for uv in 0..2 {
        if signs[uv] != CFL_SIGN_ZERO {
          assert!(cfl.context(uv) == cfl_context[uv][joint_sign]);
        }
      }
    }
  }
Thomas Daede's avatar
Thomas Daede committed
1182
1183
}

Yushin Cho's avatar
Yushin Cho committed
1184
1185
const SUPERBLOCK_TO_PLANE_SHIFT: usize = MAX_SB_SIZE_LOG2;
const SUPERBLOCK_TO_BLOCK_SHIFT: usize = MAX_MIB_SIZE_LOG2;
1186
pub const BLOCK_TO_PLANE_SHIFT: usize = MI_SIZE_LOG2;
1187
pub const LOCAL_BLOCK_MASK: usize = (1 << SUPERBLOCK_TO_BLOCK_SHIFT) - 1;
1188
1189
1190

/// Absolute offset in superblocks inside a plane, where a superblock is defined
/// to be an N*N square where N = (1 << SUPERBLOCK_TO_PLANE_SHIFT).
1191
#[derive(Clone, Copy, Debug)]
1192
pub struct SuperBlockOffset {
Michael Bebenita's avatar
Michael Bebenita committed
1193
1194
  pub x: usize,
  pub y: usize
1195
1196
1197
}

impl SuperBlockOffset {
Michael Bebenita's avatar
Michael Bebenita committed
1198
  /// Offset of a block inside the current superblock.
1199
  pub fn block_offset(self, block_x: usize, block_y: usize) -> BlockOffset {
Michael Bebenita's avatar
Michael Bebenita committed
1200
1201
1202
    BlockOffset {
      x: (self.x << SUPERBLOCK_TO_BLOCK_SHIFT) + block_x,
      y: (self.y << SUPERBLOCK_TO_BLOCK_SHIFT) + block_y
1203
    }
Michael Bebenita's avatar
Michael Bebenita committed
1204
  }
1205

Michael Bebenita's avatar
Michael Bebenita committed
1206
  /// Offset of the top-left pixel of this block.
1207
  pub fn plane_offset(self, plane: &PlaneConfig) -> PlaneOffset {
Michael Bebenita's avatar
Michael Bebenita committed
1208
    PlaneOffset {
fbossen's avatar
fbossen committed
1209
1210
      x: (self.x as isize) << (SUPERBLOCK_TO_PLANE_SHIFT - plane.xdec),
      y: (self.y as isize) << (SUPERBLOCK_TO_PLANE_SHIFT - plane.ydec)
1211
    }
Michael Bebenita's avatar
Michael Bebenita committed
1212
  }
1213
1214
1215
1216
}

/// Absolute offset in blocks inside a plane, where a block is defined
/// to be an N*N square where N = (1 << BLOCK_TO_PLANE_SHIFT).
Romain Vimont's avatar
Romain Vimont committed
1217
#[derive(Clone, Copy, Debug)]
1218
pub struct BlockOffset {
Michael Bebenita's avatar
Michael Bebenita committed
1219
1220
  pub x: usize,
  pub y: usize
1221
1222
1223
}

impl BlockOffset {
Michael Bebenita's avatar
Michael Bebenita committed
1224
  /// Offset of the superblock in which this block is located.
Romain Vimont's avatar
Romain Vimont committed
1225
  pub fn sb_offset(self) -> SuperBlockOffset {
Michael Bebenita's avatar
Michael Bebenita committed
1226
1227
1228
1229
1230
1231
1232
    SuperBlockOffset {
      x: self.x >> SUPERBLOCK_TO_BLOCK_SHIFT,
      y: self.y >> SUPERBLOCK_TO_BLOCK_SHIFT
    }
  }

  /// Offset of the top-left pixel of this block.
Romain Vimont's avatar
Romain Vimont committed
1233
  pub fn plane_offset(self, plane: &PlaneConfig) -> PlaneOffset {
Michael Bebenita's avatar
Michael Bebenita committed
1234
    PlaneOffset {
Romain Vimont's avatar
Romain Vimont committed
1235
1236
        x: (self.x >> plane.xdec << BLOCK_TO_PLANE_SHIFT) as isize,
        y: (self.y >> plane.ydec << BLOCK_TO_PLANE_SHIFT) as isize,
Michael Bebenita's avatar
Michael Bebenita committed
1237
1238
1239
    }
  }

1240
1241
1242
1243
1244
1245
1246
1247
1248
  /// Convert to plane offset without decimation
  #[inline]
  pub fn to_luma_plane_offset(self) -> PlaneOffset {
    PlaneOffset {
      x: (self.x as isize) << BLOCK_TO_PLANE_SHIFT,
      y: (self.y as isize) << BLOCK_TO_PLANE_SHIFT,
    }
  }

Romain Vimont's avatar
Romain Vimont committed
1249
  pub fn y_in_sb(self) -> usize {
Michael Bebenita's avatar
Michael Bebenita committed
1250
1251
    self.y % MAX_MIB_SIZE
  }
1252

Romain Vimont's avatar
Romain Vimont committed
1253
  pub fn with_offset(self, col_offset: isize, row_offset: isize) -> BlockOffset {
1254
1255
    let x = self.x as isize + col_offset;
    let y = self.y as isize + row_offset;
1256
1257
    debug_assert!(x >= 0);
    debug_assert!(y >= 0);
1258
1259
1260
1261
1262
1263

    BlockOffset {
      x: x as usize,
      y: y as usize
    }
  }
1264
1265
}

1266
#[derive(Clone)]
1267
pub struct Block {
Michael Bebenita's avatar
Michael Bebenita committed
1268
1269
  pub mode: PredictionMode,
  pub partition: PartitionType,
Monty Montgomery's avatar
Monty Montgomery committed
1270
  pub skip: bool,
Thomas Daede's avatar
Thomas Daede committed
1271
  pub ref_frames: [RefType; 2],
1272
  pub mv: [MotionVector; 2],
Thomas Daede's avatar
Thomas Daede committed
1273
1274
  // note: indexes are reflist index, NOT the same as libaom
  pub neighbors_ref_counts: [usize; INTER_REFS_PER_FRAME],
1275
  pub cdef_index: u8,
1276
  pub bsize: BlockSize,
1277
1278
  pub n4_w: usize, /* block width in the unit of mode_info */
  pub n4_h: usize, /* block height in the unit of mode_info */
1279
  pub txsize: TxSize,
1280
1281
1282
  // The block-level deblock_deltas are left-shifted by
  // fi.deblock.block_delta_shift and added to the frame-configured
  // deltas
1283
1284
  pub deblock_deltas: [i8; FRAME_LF_COUNT],
  pub segmentation_idx: u8
1285
1286
1287
}

impl Block {
Michael Bebenita's avatar