decodeframe.c 144 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
 */

#include <assert.h>
#include <stdlib.h>  // qsort()

Yaowu Xu's avatar
Yaowu Xu committed
15
16
17
#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
#include "./aom_scale_rtcd.h"
Jingning Han's avatar
Jingning Han committed
18
#include "./av1_rtcd.h"
Jingning Han's avatar
Jingning Han committed
19

20
#include "aom/aom_codec.h"
Yaowu Xu's avatar
Yaowu Xu committed
21
#include "aom_dsp/aom_dsp_common.h"
22
#include "aom_dsp/binary_codes_reader.h"
Jingning Han's avatar
Jingning Han committed
23
24
#include "aom_dsp/bitreader.h"
#include "aom_dsp/bitreader_buffer.h"
Yaowu Xu's avatar
Yaowu Xu committed
25
#include "aom_mem/aom_mem.h"
26
#include "aom_ports/aom_timer.h"
27
28
#include "aom_ports/mem.h"
#include "aom_ports/mem_ops.h"
Yaowu Xu's avatar
Yaowu Xu committed
29
30
#include "aom_scale/aom_scale.h"
#include "aom_util/aom_thread.h"
Jingning Han's avatar
Jingning Han committed
31

Angie Chiang's avatar
Angie Chiang committed
32
#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
33
#include "aom_util/debug_util.h"
Angie Chiang's avatar
Angie Chiang committed
34
#endif  // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
35

36
#include "av1/common/alloccommon.h"
37
#include "av1/common/cdef.h"
38
39
40
#if CONFIG_INSPECTION
#include "av1/decoder/inspection.h"
#endif
41
42
43
#include "av1/common/common.h"
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
44
#include "av1/common/entropymv.h"
45
#include "av1/common/idct.h"
46
#include "av1/common/mvref_common.h"
47
48
49
#include "av1/common/pred_common.h"
#include "av1/common/quant_common.h"
#include "av1/common/reconinter.h"
Jingning Han's avatar
Jingning Han committed
50
#include "av1/common/reconintra.h"
51
#if CONFIG_HORZONLY_FRAME_SUPERRES
52
#include "av1/common/resize.h"
53
#endif  // CONFIG_HORZONLY_FRAME_SUPERRES
54
#include "av1/common/seg_common.h"
Jingning Han's avatar
Jingning Han committed
55
#include "av1/common/thread_common.h"
56
#include "av1/common/tile_common.h"
57

58
59
60
#include "av1/decoder/decodeframe.h"
#include "av1/decoder/decodemv.h"
#include "av1/decoder/decoder.h"
Angie Chiang's avatar
Angie Chiang committed
61
62
63
#if CONFIG_LV_MAP
#include "av1/decoder/decodetxb.h"
#endif
Jingning Han's avatar
Jingning Han committed
64
#include "av1/decoder/detokenize.h"
65
#include "av1/decoder/symbolrate.h"
Jingning Han's avatar
Jingning Han committed
66

Yue Chen's avatar
Yue Chen committed
67
68
#include "av1/common/warped_motion.h"

Yaowu Xu's avatar
Yaowu Xu committed
69
#define MAX_AV1_HEADER_SIZE 80
Michael Bebenita's avatar
Michael Bebenita committed
70
#define ACCT_STR __func__
Jingning Han's avatar
Jingning Han committed
71

72
73
74
75
#if CONFIG_CFL
#include "av1/common/cfl.h"
#endif

76
77
78
79
#if CONFIG_STRIPED_LOOP_RESTORATION && !CONFIG_LOOP_RESTORATION
#error "striped_loop_restoration requires loop_restoration"
#endif

80
81
82
83
84
85
86
#if CONFIG_LOOP_RESTORATION
static void loop_restoration_read_sb_coeffs(const AV1_COMMON *const cm,
                                            MACROBLOCKD *xd,
                                            aom_reader *const r, int plane,
                                            int rtile_idx);
#endif

87
88
89
90
91
92
93
94
static struct aom_read_bit_buffer *init_read_bit_buffer(
    AV1Decoder *pbi, struct aom_read_bit_buffer *rb, const uint8_t *data,
    const uint8_t *data_end, uint8_t clear_data[MAX_AV1_HEADER_SIZE]);
static int read_compressed_header(AV1Decoder *pbi, const uint8_t *data,
                                  size_t partition_size);
static size_t read_uncompressed_header(AV1Decoder *pbi,
                                       struct aom_read_bit_buffer *rb);

Yaowu Xu's avatar
Yaowu Xu committed
95
static int is_compound_reference_allowed(const AV1_COMMON *cm) {
96
  return !frame_is_intra_only(cm);
Jingning Han's avatar
Jingning Han committed
97
98
}

Yaowu Xu's avatar
Yaowu Xu committed
99
static void setup_compound_reference_mode(AV1_COMMON *cm) {
100
  cm->comp_fwd_ref[0] = LAST_FRAME;
101
102
103
104
  cm->comp_fwd_ref[1] = LAST2_FRAME;
  cm->comp_fwd_ref[2] = LAST3_FRAME;
  cm->comp_fwd_ref[3] = GOLDEN_FRAME;

105
  cm->comp_bwd_ref[0] = BWDREF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
106
107
  cm->comp_bwd_ref[1] = ALTREF2_FRAME;
  cm->comp_bwd_ref[2] = ALTREF_FRAME;
Jingning Han's avatar
Jingning Han committed
108
109
110
111
112
113
}

static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) {
  return len != 0 && len <= (size_t)(end - start);
}

114
115
116
117
118
119
#if CONFIG_SIMPLIFY_TX_MODE
static TX_MODE read_tx_mode(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
  if (cm->all_lossless) return ONLY_4X4;
  return aom_rb_read_bit(rb) ? TX_MODE_SELECT : TX_MODE_LARGEST;
}
#else
120
121
static TX_MODE read_tx_mode(AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
  if (cm->all_lossless) return ONLY_4X4;
122
#if CONFIG_TX64X64
Urvang Joshi's avatar
Urvang Joshi committed
123
124
  TX_MODE tx_mode =
      aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
125
126
127
  if (tx_mode == ALLOW_32X32) tx_mode += aom_rb_read_bit(rb);
  return tx_mode;
#else
Yaowu Xu's avatar
Yaowu Xu committed
128
  return aom_rb_read_bit(rb) ? TX_MODE_SELECT : aom_rb_read_literal(rb, 2);
129
#endif  // CONFIG_TX64X64
130
}
131
#endif  // CONFIG_SIMPLIFY_TX_MODE
Jingning Han's avatar
Jingning Han committed
132

133
static REFERENCE_MODE read_frame_reference_mode(
Yaowu Xu's avatar
Yaowu Xu committed
134
    const AV1_COMMON *cm, struct aom_read_bit_buffer *rb) {
135
  if (is_compound_reference_allowed(cm)) {
Zoe Liu's avatar
Zoe Liu committed
136
137
138
#if CONFIG_REF_ADAPT
    return aom_rb_read_bit(rb) ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE;
#else
Yaowu Xu's avatar
Yaowu Xu committed
139
    return aom_rb_read_bit(rb)
140
               ? REFERENCE_MODE_SELECT
Yaowu Xu's avatar
Yaowu Xu committed
141
               : (aom_rb_read_bit(rb) ? COMPOUND_REFERENCE : SINGLE_REFERENCE);
Zoe Liu's avatar
Zoe Liu committed
142
#endif  // CONFIG_REF_ADAPT
143
144
145
146
  } else {
    return SINGLE_REFERENCE;
  }
}
Jingning Han's avatar
Jingning Han committed
147

148
static void inverse_transform_block(MACROBLOCKD *xd, int plane,
149
                                    const TX_TYPE tx_type,
150
                                    const TX_SIZE tx_size, uint8_t *dst,
151
152
                                    int stride, int16_t scan_line, int eob,
                                    int reduced_tx_set) {
Jingning Han's avatar
Jingning Han committed
153
  struct macroblockd_plane *const pd = &xd->plane[plane];
154
  tran_low_t *const dqcoeff = pd->dqcoeff;
Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
155
156
  av1_inverse_transform_block(xd, dqcoeff, plane, tx_type, tx_size, dst, stride,
                              eob, reduced_tx_set);
157
  memset(dqcoeff, 0, (scan_line + 1) * sizeof(dqcoeff[0]));
Jingning Han's avatar
Jingning Han committed
158
159
}

160
161
162
static void predict_and_reconstruct_intra_block(
    AV1_COMMON *cm, MACROBLOCKD *const xd, aom_reader *const r,
    MB_MODE_INFO *const mbmi, int plane, int row, int col, TX_SIZE tx_size) {
163
  PLANE_TYPE plane_type = get_plane_type(plane);
Luc Trudeau's avatar
Luc Trudeau committed
164
  av1_predict_intra_block_facade(cm, xd, plane, col, row, tx_size);
Jingning Han's avatar
Jingning Han committed
165
166

  if (!mbmi->skip) {
167
    struct macroblockd_plane *const pd = &xd->plane[plane];
168
169
170
171
#if TXCOEFF_TIMER
    struct aom_usec_timer timer;
    aom_usec_timer_start(&timer);
#endif
Angie Chiang's avatar
Angie Chiang committed
172
173
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
174
    int eob;
Luc Trudeau's avatar
Luc Trudeau committed
175
    av1_read_coeffs_txb_facade(cm, xd, r, row, col, plane, tx_size,
176
                               &max_scan_line, &eob);
177
    // tx_type will be read out in av1_read_coeffs_txb_facade
Luc Trudeau's avatar
Luc Trudeau committed
178
    const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, row, col, tx_size);
Angie Chiang's avatar
Angie Chiang committed
179
#else   // CONFIG_LV_MAP
Luc Trudeau's avatar
Luc Trudeau committed
180
    const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, row, col, tx_size);
Angie Chiang's avatar
Angie Chiang committed
181
    const SCAN_ORDER *scan_order = get_scan(cm, tx_size, tx_type, mbmi);
182
183
    int16_t max_scan_line = 0;
    const int eob =
184
        av1_decode_block_tokens(cm, xd, plane, scan_order, col, row, tx_size,
185
                                tx_type, &max_scan_line, r, mbmi->segment_id);
Angie Chiang's avatar
Angie Chiang committed
186
#endif  // CONFIG_LV_MAP
187
188
189
190
191
192
193

#if TXCOEFF_TIMER
    aom_usec_timer_mark(&timer);
    const int64_t elapsed_time = aom_usec_timer_elapsed(&timer);
    cm->txcoeff_timer += elapsed_time;
    ++cm->txb_count;
#endif
194
195
196
    if (eob) {
      uint8_t *dst =
          &pd->dst.buf[(row * pd->dst.stride + col) << tx_size_wide_log2[0]];
197
      inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
198
                              max_scan_line, eob, cm->reduced_tx_set_used);
199
    }
Jingning Han's avatar
Jingning Han committed
200
  }
201
#if CONFIG_CFL
202
  if (plane == AOM_PLANE_Y && xd->cfl.store_y && is_cfl_allowed(mbmi)) {
203
    cfl_store_tx(xd, row, col, tx_size, mbmi->sb_type);
204
  }
Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
205
#endif  // CONFIG_CFL
Jingning Han's avatar
Jingning Han committed
206
207
}

Angie Chiang's avatar
Angie Chiang committed
208
209
static void decode_reconstruct_tx(AV1_COMMON *cm, MACROBLOCKD *const xd,
                                  aom_reader *r, MB_MODE_INFO *const mbmi,
210
                                  int plane, BLOCK_SIZE plane_bsize,
211
                                  int blk_row, int blk_col, int block,
Angie Chiang's avatar
Angie Chiang committed
212
213
214
215
                                  TX_SIZE tx_size, int *eob_total, int mi_row,
                                  int mi_col) {
  (void)mi_row;
  (void)mi_col;
216
  const struct macroblockd_plane *const pd = &xd->plane[plane];
217
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
218
219
  const int tx_row = blk_row >> (1 - pd->subsampling_y);
  const int tx_col = blk_col >> (1 - pd->subsampling_x);
220
  const TX_SIZE plane_tx_size =
221
      plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
222
            : mbmi->inter_tx_size[tx_row][tx_col];
223
  // Scale to match transform block unit.
224
225
  const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
226

227
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
228

229
230
231
232
233
  if (tx_size == plane_tx_size
#if DISABLE_VARTX_FOR_CHROMA
      || pd->subsampling_x || pd->subsampling_y
#endif  // DISABLE_VARTX_FOR_CHROMA
      ) {
234
    PLANE_TYPE plane_type = get_plane_type(plane);
235
236
237
238
#if TXCOEFF_TIMER
    struct aom_usec_timer timer;
    aom_usec_timer_start(&timer);
#endif
Angie Chiang's avatar
Angie Chiang committed
239
240
#if CONFIG_LV_MAP
    int16_t max_scan_line = 0;
241
    int eob;
Luc Trudeau's avatar
Luc Trudeau committed
242
243
    av1_read_coeffs_txb_facade(cm, xd, r, blk_row, blk_col, plane, tx_size,
                               &max_scan_line, &eob);
244
    // tx_type will be read out in av1_read_coeffs_txb_facade
hui su's avatar
hui su committed
245
    const TX_TYPE tx_type =
Luc Trudeau's avatar
Luc Trudeau committed
246
        av1_get_tx_type(plane_type, xd, blk_row, blk_col, tx_size);
Angie Chiang's avatar
Angie Chiang committed
247
#else   // CONFIG_LV_MAP
hui su's avatar
hui su committed
248
    const TX_TYPE tx_type =
Luc Trudeau's avatar
Luc Trudeau committed
249
        av1_get_tx_type(plane_type, xd, blk_row, blk_col, tx_size);
250
    const SCAN_ORDER *sc = get_scan(cm, tx_size, tx_type, mbmi);
251
    int16_t max_scan_line = 0;
252
253
254
    const int eob =
        av1_decode_block_tokens(cm, xd, plane, sc, blk_col, blk_row, tx_size,
                                tx_type, &max_scan_line, r, mbmi->segment_id);
Angie Chiang's avatar
Angie Chiang committed
255
#endif  // CONFIG_LV_MAP
256
257
258
259
260
261
262
263

#if TXCOEFF_TIMER
    aom_usec_timer_mark(&timer);
    const int64_t elapsed_time = aom_usec_timer_elapsed(&timer);
    cm->txcoeff_timer += elapsed_time;
    ++cm->txb_count;
#endif

Angie Chiang's avatar
Angie Chiang committed
264
    uint8_t *dst =
265
        &pd->dst
Angie Chiang's avatar
Angie Chiang committed
266
267
268
269
270
             .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
    inverse_transform_block(xd, plane, tx_type, tx_size, dst, pd->dst.stride,
                            max_scan_line, eob, cm->reduced_tx_set_used);
#if CONFIG_MISMATCH_DEBUG
    int pixel_c, pixel_r;
271
272
    int blk_w = block_size_wide[bsize];
    int blk_h = block_size_high[bsize];
Angie Chiang's avatar
Angie Chiang committed
273
274
275
276
277
    mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, blk_col, blk_row,
                    pd->subsampling_x, pd->subsampling_y);
    mismatch_check_block_tx(dst, pd->dst.stride, plane, pixel_c, pixel_r, blk_w,
                            blk_h);
#endif
278
279
    *eob_total += eob;
  } else {
280
    const TX_SIZE sub_txs = sub_tx_size_map[1][tx_size];
281
282
    assert(IMPLIES(tx_size <= TX_4X4, sub_txs == tx_size));
    assert(IMPLIES(tx_size > TX_4X4, sub_txs < tx_size));
283
284
285
    const int bsw = tx_size_wide_unit[sub_txs];
    const int bsh = tx_size_high_unit[sub_txs];
    const int sub_step = bsw * bsh;
286

287
    assert(bsw > 0 && bsh > 0);
288

289
290
291
292
    for (int row = 0; row < tx_size_high_unit[tx_size]; row += bsh) {
      for (int col = 0; col < tx_size_wide_unit[tx_size]; col += bsw) {
        const int offsetr = blk_row + row;
        const int offsetc = blk_col + col;
293

294
        if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
295

296
        decode_reconstruct_tx(cm, xd, r, mbmi, plane, plane_bsize, offsetr,
Angie Chiang's avatar
Angie Chiang committed
297
298
                              offsetc, block, sub_txs, eob_total, mi_row,
                              mi_col);
299
300
        block += sub_step;
      }
301
302
303
    }
  }
}
Jingning Han's avatar
Jingning Han committed
304

305
306
307
static void set_offsets(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                        BLOCK_SIZE bsize, int mi_row, int mi_col, int bw,
                        int bh, int x_mis, int y_mis) {
Jingning Han's avatar
Jingning Han committed
308
309
310
311
312
313
314
315
  const int offset = mi_row * cm->mi_stride + mi_col;
  const TileInfo *const tile = &xd->tile;

  xd->mi = cm->mi_grid_visible + offset;
  xd->mi[0] = &cm->mi[offset];
  // TODO(slavarnway): Generate sb_type based on bwl and bhl, instead of
  // passing bsize from decode_partition().
  xd->mi[0]->mbmi.sb_type = bsize;
316
317
318
#if CONFIG_RD_DEBUG
  xd->mi[0]->mbmi.mi_row = mi_row;
  xd->mi[0]->mbmi.mi_col = mi_col;
319
320
#endif
#if CONFIG_CFL
321
322
  xd->cfl.mi_row = mi_row;
  xd->cfl.mi_col = mi_col;
323
#endif
324
325

  assert(x_mis && y_mis);
326
  for (int x = 1; x < x_mis; ++x) xd->mi[x] = xd->mi[0];
327
  int idx = cm->mi_stride;
328
  for (int y = 1; y < y_mis; ++y) {
329
330
331
    memcpy(&xd->mi[idx], &xd->mi[0], x_mis * sizeof(xd->mi[0]));
    idx += cm->mi_stride;
  }
Jingning Han's avatar
Jingning Han committed
332

Jingning Han's avatar
Jingning Han committed
333
  set_plane_n4(xd, bw, bh);
Jingning Han's avatar
Jingning Han committed
334
335
  set_skip_context(xd, mi_row, mi_col);

336
337
338
  // Distance of Mb to the various image edges. These are specified to 8th pel
  // as they are always compared to values that are in 1/8th pel units
  set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw,
339
#if CONFIG_DEPENDENT_HORZTILES
340
341
342
                 cm->dependent_horz_tiles,
#endif  // CONFIG_DEPENDENT_HORZTILES
                 cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
343

344
345
  av1_setup_dst_planes(xd->plane, bsize, get_frame_new_buffer(cm), mi_row,
                       mi_col);
Jingning Han's avatar
Jingning Han committed
346
347
}

348
349
static void decode_mbmi_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                              int mi_row, int mi_col, aom_reader *r,
350
#if CONFIG_EXT_PARTITION_TYPES
351
                              PARTITION_TYPE partition,
352
#endif  // CONFIG_EXT_PARTITION_TYPES
353
                              BLOCK_SIZE bsize) {
Yaowu Xu's avatar
Yaowu Xu committed
354
  AV1_COMMON *const cm = &pbi->common;
355
356
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
Yaowu Xu's avatar
Yaowu Xu committed
357
358
  const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
359

Michael Bebenita's avatar
Michael Bebenita committed
360
361
362
#if CONFIG_ACCOUNTING
  aom_accounting_set_context(&pbi->accounting, mi_col, mi_row);
#endif
363
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
364
365
366
#if CONFIG_EXT_PARTITION_TYPES
  xd->mi[0]->mbmi.partition = partition;
#endif
Yaowu Xu's avatar
Yaowu Xu committed
367
  av1_read_mode_info(pbi, xd, mi_row, mi_col, r, x_mis, y_mis);
Jingning Han's avatar
Jingning Han committed
368
369
370
371
  if (bsize >= BLOCK_8X8 && (cm->subsampling_x || cm->subsampling_y)) {
    const BLOCK_SIZE uv_subsize =
        ss_size_lookup[bsize][cm->subsampling_x][cm->subsampling_y];
    if (uv_subsize == BLOCK_INVALID)
Yaowu Xu's avatar
Yaowu Xu committed
372
      aom_internal_error(xd->error_info, AOM_CODEC_CORRUPT_FRAME,
373
                         "Invalid block size.");
Jingning Han's avatar
Jingning Han committed
374
375
  }

376
377
  int reader_corrupted_flag = aom_reader_has_error(r);
  aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
378
379
380
381
382
383
384
385
386
387
388
389
}

static void decode_token_and_recon_block(AV1Decoder *const pbi,
                                         MACROBLOCKD *const xd, int mi_row,
                                         int mi_col, aom_reader *r,
                                         BLOCK_SIZE bsize) {
  AV1_COMMON *const cm = &pbi->common;
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
  const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
  const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);

390
391
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis);
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
392
#if CONFIG_CFL
393
  CFL_CTX *const cfl = &xd->cfl;
394
395
  cfl->is_chroma_reference = is_chroma_reference(
      mi_row, mi_col, bsize, cfl->subsampling_x, cfl->subsampling_y);
396
#endif  // CONFIG_CFL
397

398
  if (cm->delta_q_present_flag) {
399
    for (int i = 0; i < MAX_SEGMENTS; i++) {
Fangwen Fu's avatar
Fangwen Fu committed
400
#if CONFIG_EXT_DELTA_Q
401
402
      const int current_qindex =
          av1_get_qindex(&cm->seg, i, xd->current_qindex);
Fangwen Fu's avatar
Fangwen Fu committed
403
#else
404
405
      const int current_qindex = xd->current_qindex;
#endif  // CONFIG_EXT_DELTA_Q
406
      for (int j = 0; j < av1_num_planes(cm); ++j) {
407
408
409
410
411
        const int dc_delta_q =
            j == 0 ? cm->y_dc_delta_q
                   : (j == 1 ? cm->u_dc_delta_q : cm->v_dc_delta_q);
        const int ac_delta_q =
            j == 0 ? 0 : (j == 1 ? cm->u_ac_delta_q : cm->v_ac_delta_q);
412
413
414
415
        xd->plane[j].seg_dequant_QTX[i][0] =
            av1_dc_quant_QTX(current_qindex, dc_delta_q, cm->bit_depth);
        xd->plane[j].seg_dequant_QTX[i][1] =
            av1_ac_quant_QTX(current_qindex, ac_delta_q, cm->bit_depth);
416
      }
417
418
    }
  }
419
  if (mbmi->skip) av1_reset_skip_context(xd, mi_row, mi_col, bsize);
420

421
  if (!is_inter_block(mbmi)) {
422
423
    const int num_planes = av1_num_planes(cm);
    for (int plane = 0; plane < AOMMIN(2, num_planes); ++plane) {
424
      if (mbmi->palette_mode_info.palette_size[plane])
Yaowu Xu's avatar
Yaowu Xu committed
425
        av1_decode_palette_tokens(xd, plane, r);
Jingning Han's avatar
Jingning Han committed
426
    }
427

428
    for (int plane = 0; plane < num_planes; ++plane) {
429
      const struct macroblockd_plane *const pd = &xd->plane[plane];
430
      const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
431
432
      const int stepr = tx_size_high_unit[tx_size];
      const int stepc = tx_size_wide_unit[tx_size];
433
      const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
434
      int row, col;
435
436
      const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
      const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
437
438
      if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
                               pd->subsampling_y))
439
        continue;
440
441
442
443
444
445
446
447
448
449
      int blk_row, blk_col;
      const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, pd);
      int mu_blocks_wide =
          block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0];
      int mu_blocks_high =
          block_size_high[max_unit_bsize] >> tx_size_high_log2[0];
      mu_blocks_wide = AOMMIN(max_blocks_wide, mu_blocks_wide);
      mu_blocks_high = AOMMIN(max_blocks_high, mu_blocks_high);

      for (row = 0; row < max_blocks_high; row += mu_blocks_high) {
450
        const int unit_height = AOMMIN(mu_blocks_high + row, max_blocks_high);
451
452
453
454
455
456
457
458
459
        for (col = 0; col < max_blocks_wide; col += mu_blocks_wide) {
          const int unit_width = AOMMIN(mu_blocks_wide + col, max_blocks_wide);

          for (blk_row = row; blk_row < unit_height; blk_row += stepr)
            for (blk_col = col; blk_col < unit_width; blk_col += stepc)
              predict_and_reconstruct_intra_block(cm, xd, r, mbmi, plane,
                                                  blk_row, blk_col, tx_size);
        }
      }
460
461
    }
  } else {
462
    for (int ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
463
      const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
Alex Converse's avatar
Alex Converse committed
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
      if (frame < LAST_FRAME) {
#if CONFIG_INTRABC
        assert(is_intrabc_block(mbmi));
        assert(frame == INTRA_FRAME);
        assert(ref == 0);
#else
        assert(0);
#endif  // CONFIG_INTRABC
      } else {
        RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];

        xd->block_refs[ref] = ref_buf;
        if ((!av1_is_valid_scale(&ref_buf->sf)))
          aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
                             "Reference frame has invalid dimensions");
        av1_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col,
                             &ref_buf->sf);
      }
482
    }
483

484
    av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
485

Yue Chen's avatar
Yue Chen committed
486
    if (mbmi->motion_mode == OBMC_CAUSAL) {
487
      av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
488
    }
Angie Chiang's avatar
Angie Chiang committed
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503

#if CONFIG_MISMATCH_DEBUG
    for (int plane = 0; plane < 3; ++plane) {
      const struct macroblockd_plane *pd = &xd->plane[plane];
      int pixel_c, pixel_r;
      mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, 0, 0,
                      pd->subsampling_x, pd->subsampling_y);
      if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
                               pd->subsampling_y))
        continue;
      mismatch_check_block_pre(pd->dst.buf, pd->dst.stride, plane, pixel_c,
                               pixel_r, pd->width, pd->height);
    }
#endif

504
505
506
    // Reconstruction
    if (!mbmi->skip) {
      int eobtotal = 0;
507
      for (int plane = 0; plane < av1_num_planes(cm); ++plane) {
Jingning Han's avatar
Jingning Han committed
508
        const struct macroblockd_plane *const pd = &xd->plane[plane];
509
510
511
512
513
        if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
                                 pd->subsampling_y))
          continue;
        const BLOCK_SIZE bsizec =
            scale_chroma_bsize(bsize, pd->subsampling_x, pd->subsampling_y);
514
        const BLOCK_SIZE plane_bsize = get_plane_block_size(bsizec, pd);
515
516
        const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
        const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
517
        int row, col;
518

519
520
521
522
523
524
525
526
527
        const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, pd);
        int mu_blocks_wide =
            block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0];
        int mu_blocks_high =
            block_size_high[max_unit_bsize] >> tx_size_high_log2[0];

        mu_blocks_wide = AOMMIN(max_blocks_wide, mu_blocks_wide);
        mu_blocks_high = AOMMIN(max_blocks_high, mu_blocks_high);

528
        TX_SIZE max_tx_size = get_vartx_max_txsize(
529
            xd, plane_bsize, pd->subsampling_x || pd->subsampling_y);
530
531
532
533
534
535
536
537
538
#if DISABLE_VARTX_FOR_CHROMA == 2
        // If the luma transform size is split at least one level, split the
        // chroma by one level. Otherwise use the  largest possible trasnform
        // size for chroma.
        if (plane && (pd->subsampling_x || pd->subsampling_y)) {
          const TX_SIZE l_max_tx_size = get_vartx_max_txsize(xd, bsizec, 0);
          const int is_split =
              (l_max_tx_size != mbmi->inter_tx_size[0][0] && bsize == bsizec &&
               txsize_to_bsize[l_max_tx_size] == bsizec);
539
          if (is_split) max_tx_size = sub_tx_size_map[1][max_tx_size];
540
541
        }
#endif  // DISABLE_VARTX_FOR_CHROMA == 2
542
543
        const int bh_var_tx = tx_size_high_unit[max_tx_size];
        const int bw_var_tx = tx_size_wide_unit[max_tx_size];
544
545
546
        int block = 0;
        int step =
            tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
547
548
549
550
551
552
553
554
555
556
557
558

        for (row = 0; row < max_blocks_high; row += mu_blocks_high) {
          for (col = 0; col < max_blocks_wide; col += mu_blocks_wide) {
            int blk_row, blk_col;
            const int unit_height =
                AOMMIN(mu_blocks_high + row, max_blocks_high);
            const int unit_width =
                AOMMIN(mu_blocks_wide + col, max_blocks_wide);
            for (blk_row = row; blk_row < unit_height; blk_row += bh_var_tx) {
              for (blk_col = col; blk_col < unit_width; blk_col += bw_var_tx) {
                decode_reconstruct_tx(cm, xd, r, mbmi, plane, plane_bsize,
                                      blk_row, blk_col, block, max_tx_size,
Angie Chiang's avatar
Angie Chiang committed
559
                                      &eobtotal, mi_row, mi_col);
560
561
562
                block += step;
              }
            }
563
564
          }
        }
565
      }
Jingning Han's avatar
Jingning Han committed
566
567
    }
  }
568
#if CONFIG_CFL
569
  if (mbmi->uv_mode != UV_CFL_PRED) {
570
    if (!cfl->is_chroma_reference && is_inter_block(mbmi) &&
571
        is_cfl_allowed(mbmi)) {
572
573
574
      cfl_store_block(xd, mbmi->sb_type, mbmi->tx_size);
    }
  }
575
#endif  // CONFIG_CFL
Jingning Han's avatar
Jingning Han committed
576

577
578
  int reader_corrupted_flag = aom_reader_has_error(r);
  aom_merge_corrupted_flag(&xd->corrupted, reader_corrupted_flag);
Jingning Han's avatar
Jingning Han committed
579
580
}

581
582
583
584
585
586
static void decode_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                         int mi_row, int mi_col, aom_reader *r,
#if CONFIG_EXT_PARTITION_TYPES
                         PARTITION_TYPE partition,
#endif  // CONFIG_EXT_PARTITION_TYPES
                         BLOCK_SIZE bsize) {
587
  decode_mbmi_block(pbi, xd, mi_row, mi_col, r,
588
589
590
591
#if CONFIG_EXT_PARTITION_TYPES
                    partition,
#endif
                    bsize);
592

593
  decode_token_and_recon_block(pbi, xd, mi_row, mi_col, r, bsize);
594
595
}

596
597
static PARTITION_TYPE read_partition(MACROBLOCKD *xd, int mi_row, int mi_col,
                                     aom_reader *r, int has_rows, int has_cols,
598
599
                                     BLOCK_SIZE bsize) {
  const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize);
600
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
Jingning Han's avatar
Jingning Han committed
601

602
  if (!has_rows && !has_cols) return PARTITION_SPLIT;
Jingning Han's avatar
Jingning Han committed
603

604
605
  assert(ctx >= 0);
  aom_cdf_prob *partition_cdf = ec_ctx->partition_cdf[ctx];
606
  if (has_rows && has_cols) {
607
608
    return (PARTITION_TYPE)aom_read_symbol(
        r, partition_cdf, partition_cdf_length(bsize), ACCT_STR);
609
  } else if (!has_rows && has_cols) {
610
611
    assert(bsize > BLOCK_8X8);
    aom_cdf_prob cdf[2];
612
    partition_gather_vert_alike(cdf, partition_cdf, bsize);
613
    assert(cdf[1] == AOM_ICDF(CDF_PROB_TOP));
614
615
616
    return aom_read_cdf(r, cdf, 2, ACCT_STR) ? PARTITION_SPLIT : PARTITION_HORZ;
  } else {
    assert(has_rows && !has_cols);
617
618
    assert(bsize > BLOCK_8X8);
    aom_cdf_prob cdf[2];
619
    partition_gather_horz_alike(cdf, partition_cdf, bsize);
620
    assert(cdf[1] == AOM_ICDF(CDF_PROB_TOP));
621
    return aom_read_cdf(r, cdf, 2, ACCT_STR) ? PARTITION_SPLIT : PARTITION_VERT;
622
  }
Jingning Han's avatar
Jingning Han committed
623
624
625
}

// TODO(slavarnway): eliminate bsize and subsize in future commits
Yaowu Xu's avatar
Yaowu Xu committed
626
627
static void decode_partition(AV1Decoder *const pbi, MACROBLOCKD *const xd,
                             int mi_row, int mi_col, aom_reader *r,
628
                             BLOCK_SIZE bsize) {
Yaowu Xu's avatar
Yaowu Xu committed
629
  AV1_COMMON *const cm = &pbi->common;
630
  const int num_8x8_wh = mi_size_wide[bsize];
Jingning Han's avatar
Jingning Han committed
631
  const int hbs = num_8x8_wh >> 1;
632
633
634
#if CONFIG_EXT_PARTITION_TYPES && CONFIG_EXT_PARTITION_TYPES_AB
  const int qbs = num_8x8_wh >> 2;
#endif
Jingning Han's avatar
Jingning Han committed
635
636
  PARTITION_TYPE partition;
  BLOCK_SIZE subsize;
637
#if CONFIG_EXT_PARTITION_TYPES
638
  const int quarter_step = num_8x8_wh / 4;
639
640
641
#if !CONFIG_EXT_PARTITION_TYPES_AB
  BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
#endif
642
#endif
Jingning Han's avatar
Jingning Han committed
643
644
645
  const int has_rows = (mi_row + hbs) < cm->mi_rows;
  const int has_cols = (mi_col + hbs) < cm->mi_cols;

646
  if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
Jingning Han's avatar
Jingning Han committed
647

648
  partition = (bsize < BLOCK_8X8) ? PARTITION_NONE
649
                                  : read_partition(xd, mi_row, mi_col, r,
650
                                                   has_rows, has_cols, bsize);
Jingning Han's avatar
Jingning Han committed
651
  subsize = subsize_lookup[partition][bsize];  // get_subsize(bsize, partition);
652

653
654
655
656
657
658
659
660
661
  // Check the bitstream is conformant: if there is subsampling on the
  // chroma planes, subsize must subsample to a valid block size.
  const struct macroblockd_plane *const pd_u = &xd->plane[1];
  if (get_plane_block_size(subsize, pd_u) == BLOCK_INVALID) {
    aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
                       "Block size %dx%d invalid with this subsampling mode",
                       block_size_wide[subsize], block_size_high[subsize]);
  }

662
663
664
665
666
667
668
669
670
671
672
673
#define DEC_BLOCK_STX_ARG
#if CONFIG_EXT_PARTITION_TYPES
#define DEC_BLOCK_EPT_ARG partition,
#else
#define DEC_BLOCK_EPT_ARG
#endif
#define DEC_BLOCK(db_r, db_c, db_subsize)                   \
  decode_block(pbi, xd, DEC_BLOCK_STX_ARG(db_r), (db_c), r, \
               DEC_BLOCK_EPT_ARG(db_subsize))
#define DEC_PARTITION(db_r, db_c, db_subsize) \
  decode_partition(pbi, xd, DEC_BLOCK_STX_ARG(db_r), (db_c), r, (db_subsize))

674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
  switch (partition) {
    case PARTITION_NONE: DEC_BLOCK(mi_row, mi_col, subsize); break;
    case PARTITION_HORZ:
      DEC_BLOCK(mi_row, mi_col, subsize);
      if (has_rows) DEC_BLOCK(mi_row + hbs, mi_col, subsize);
      break;
    case PARTITION_VERT:
      DEC_BLOCK(mi_row, mi_col, subsize);
      if (has_cols) DEC_BLOCK(mi_row, mi_col + hbs, subsize);
      break;
    case PARTITION_SPLIT:
      DEC_PARTITION(mi_row, mi_col, subsize);
      DEC_PARTITION(mi_row, mi_col + hbs, subsize);
      DEC_PARTITION(mi_row + hbs, mi_col, subsize);
      DEC_PARTITION(mi_row + hbs, mi_col + hbs, subsize);
      break;
690
#if CONFIG_EXT_PARTITION_TYPES
691
#if CONFIG_EXT_PARTITION_TYPES_AB
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
    case PARTITION_HORZ_A:
      DEC_BLOCK(mi_row, mi_col, get_subsize(bsize, PARTITION_HORZ_4));
      DEC_BLOCK(mi_row + qbs, mi_col, get_subsize(bsize, PARTITION_HORZ_4));
      DEC_BLOCK(mi_row + hbs, mi_col, subsize);
      break;
    case PARTITION_HORZ_B:
      DEC_BLOCK(mi_row, mi_col, subsize);
      DEC_BLOCK(mi_row + hbs, mi_col, get_subsize(bsize, PARTITION_HORZ_4));
      if (mi_row + 3 * qbs < cm->mi_rows)
        DEC_BLOCK(mi_row + 3 * qbs, mi_col,
                  get_subsize(bsize, PARTITION_HORZ_4));
      break;
    case PARTITION_VERT_A:
      DEC_BLOCK(mi_row, mi_col, get_subsize(bsize, PARTITION_VERT_4));
      DEC_BLOCK(mi_row, mi_col + qbs, get_subsize(bsize, PARTITION_VERT_4));
      DEC_BLOCK(mi_row, mi_col + hbs, subsize);
      break;
    case PARTITION_VERT_B:
      DEC_BLOCK(mi_row, mi_col, subsize);
      DEC_BLOCK(mi_row, mi_col + hbs, get_subsize(bsize, PARTITION_VERT_4));
      if (mi_col + 3 * qbs < cm->mi_cols)
        DEC_BLOCK(mi_row, mi_col + 3 * qbs,
                  get_subsize(bsize, PARTITION_VERT_4));
      break;
716
#else
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
    case PARTITION_HORZ_A:
      DEC_BLOCK(mi_row, mi_col, bsize2);
      DEC_BLOCK(mi_row, mi_col + hbs, bsize2);
      DEC_BLOCK(mi_row + hbs, mi_col, subsize);
      break;
    case PARTITION_HORZ_B:
      DEC_BLOCK(mi_row, mi_col, subsize);
      DEC_BLOCK(mi_row + hbs, mi_col, bsize2);
      DEC_BLOCK(mi_row + hbs, mi_col + hbs, bsize2);
      break;
    case PARTITION_VERT_A:
      DEC_BLOCK(mi_row, mi_col, bsize2);
      DEC_BLOCK(mi_row + hbs, mi_col, bsize2);
      DEC_BLOCK(mi_row, mi_col + hbs, subsize);
      break;
    case PARTITION_VERT_B:
      DEC_BLOCK(mi_row, mi_col, subsize);
      DEC_BLOCK(mi_row, mi_col + hbs, bsize2);
      DEC_BLOCK(mi_row + hbs, mi_col + hbs, bsize2);
      break;
737
#endif
738
    case PARTITION_HORZ_4:
739
      for (int i = 0; i < 4; ++i) {
740
741
742
743
744
745
        int this_mi_row = mi_row + i * quarter_step;
        if (i > 0 && this_mi_row >= cm->mi_rows) break;
        DEC_BLOCK(this_mi_row, mi_col, subsize);
      }
      break;
    case PARTITION_VERT_4:
746
      for (int i = 0; i < 4; ++i) {
747
748
749
750
751
        int this_mi_col = mi_col + i * quarter_step;
        if (i > 0 && this_mi_col >= cm->mi_cols) break;
        DEC_BLOCK(mi_row, this_mi_col, subsize);
      }
      break;
752
#endif  // CONFIG_EXT_PARTITION_TYPES
753
    default: assert(0 && "Invalid partition type");
Jingning Han's avatar
Jingning Han committed
754
755
  }

756
757
758
759
760
#undef DEC_PARTITION
#undef DEC_BLOCK
#undef DEC_BLOCK_EPT_ARG
#undef DEC_BLOCK_STX_ARG

761
#if CONFIG_EXT_PARTITION_TYPES
762
  update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
763
#else
Jingning Han's avatar
Jingning Han committed
764
765
766
  // update partition context
  if (bsize >= BLOCK_8X8 &&
      (bsize == BLOCK_8X8 || partition != PARTITION_SPLIT))
767
    update_partition_context(xd, mi_row, mi_col, subsize, bsize);
768
#endif  // CONFIG_EXT_PARTITION_TYPES
769

770
#if CONFIG_LPF_SB
771
772
773
774
775
776
777
778
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
#if CONFIG_LOOPFILTER_LEVEL
  if (bsize == cm->sb_size && !USE_GUESS_LEVEL) {
    int lvl_idx;
    int filt_lvl[4];
    if (mi_row == 0 && mi_col == 0) {
      filt_lvl[0] = aom_read_literal(r, 6, ACCT_STR);
      filt_lvl[1] = aom_read_literal(r, 6, ACCT_STR);
      if (filt_lvl[0] || filt_lvl[1]) {
        filt_lvl[2] = aom_read_literal(r, 6, ACCT_STR);
        filt_lvl[3] = aom_read_literal(r, 6, ACCT_STR);
      }
      for (lvl_idx = 0; lvl_idx < 4; ++lvl_idx) {
        cm->mi_grid_visible[0]->mbmi.reuse_sb_lvl[lvl_idx] = 0;
        cm->mi_grid_visible[0]->mbmi.delta[lvl_idx] = 0;
        cm->mi_grid_visible[0]->mbmi.sign[lvl_idx] = 0;
      }
    } else {
      int prev_mi_row, prev_mi_col;
      if (mi_col - MAX_MIB_SIZE < 0) {
        prev_mi_row = mi_row - MAX_MIB_SIZE;
        prev_mi_col = mi_col;
      } else {
        prev_mi_row = mi_row;
        prev_mi_col = mi_col - MAX_MIB_SIZE;
      }

      MB_MODE_INFO *curr_mbmi =
          &cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]->mbmi;
      MB_MODE_INFO *prev_mbmi =
          &cm->mi_grid_visible[prev_mi_row * cm->mi_stride + prev_mi_col]->mbmi;
      for (lvl_idx = 0; lvl_idx < 4; ++lvl_idx) {
        const uint8_t prev_lvl = prev_mbmi->filt_lvl[lvl_idx];

        const int reuse_ctx = prev_mbmi->reuse_sb_lvl[lvl_idx];
        const int reuse_prev_lvl = aom_read_symbol(
            r, xd->tile_ctx->lpf_reuse_cdf[lvl_idx][reuse_ctx], 2, ACCT_STR);
        curr_mbmi->reuse_sb_lvl[lvl_idx] = reuse_prev_lvl;

        if (reuse_prev_lvl) {
          filt_lvl[lvl_idx] = prev_lvl;
          curr_mbmi->delta[lvl_idx] = 0;
          curr_mbmi->sign[lvl_idx] = 0;
        } else {
          const int delta_ctx = prev_mbmi->delta[lvl_idx];
          unsigned int delta = aom_read_symbol(
              r, xd->tile_ctx->lpf_delta_cdf[lvl_idx][delta_ctx], DELTA_RANGE,
              ACCT_STR);
          curr_mbmi->delta[lvl_idx] = delta;
          delta *= LPF_STEP;

          if (delta) {
            const int sign_ctx = prev_mbmi->sign[lvl_idx];
            const int sign = aom_read_symbol(
                r, xd->tile_ctx->lpf_sign_cdf[lvl_idx][reuse_ctx][sign_ctx], 2,
                ACCT_STR);
            curr_mbmi->sign[lvl_idx] = sign;
            filt_lvl[lvl_idx] = sign ? prev_lvl + delta : prev_lvl - delta;
          } else {
            filt_lvl[lvl_idx] = prev_lvl;
            curr_mbmi->sign[lvl_idx] = 0;
          }
        }
      }
    }

    av1_loop_filter_sb_level_init(cm, mi_row, mi_col, 0, 0, filt_lvl[0]);
    av1_loop_filter_sb_level_init(cm, mi_row, mi_col, 0, 1, filt_lvl[1]);
    av1_loop_filter_sb_level_init(cm, mi_row, mi_col, 1, 0, filt_lvl[2]);
    av1_loop_filter_sb_level_init(cm, mi_row, mi_col, 2, 0, filt_lvl[3]);
  }
#else
842
  if (bsize == cm->sb_size && !USE_GUESS_LEVEL) {
843
844
845
    int filt_lvl;
    if (mi_row == 0 && mi_col == 0) {
      filt_lvl = aom_read_literal(r, 6, ACCT_STR);
846
847
848
      cm->mi_grid_visible[0]->mbmi.reuse_sb_lvl = 0;
      cm->mi_grid_visible[0]->mbmi.delta = 0;
      cm->mi_grid_visible[0]->mbmi.sign = 0;
849
850
851
852
853
854
855
856
857
    } else {
      int prev_mi_row, prev_mi_col;
      if (mi_col - MAX_MIB_SIZE < 0) {
        prev_mi_row = mi_row - MAX_MIB_SIZE;
        prev_mi_col = mi_col;
      } else {
        prev_mi_row = mi_row;
        prev_mi_col = mi_col - MAX_MIB_SIZE;
      }
858

859
860
861
862
863
864
865
866
867
868
      MB_MODE_INFO *curr_mbmi =
          &cm->mi_grid_visible[mi_row * cm->mi_stride + mi_col]->mbmi;
      MB_MODE_INFO *prev_mbmi =
          &cm->mi_grid_visible[prev_mi_row * cm->mi_stride + prev_mi_col]->mbmi;
      const uint8_t prev_lvl = prev_mbmi->filt_lvl;

      const int reuse_ctx = prev_mbmi->reuse_sb_lvl;
      const int reuse_prev_lvl = aom_read_symbol(
          r, xd->tile_ctx->lpf_reuse_cdf[reuse_ctx], 2, ACCT_STR);
      curr_mbmi->reuse_sb_lvl = reuse_prev_lvl;
869

870
      if (reuse_prev_lvl) {
871
        filt_lvl = prev_lvl;
872
873
        curr_mbmi->delta = 0;
        curr_mbmi->sign = 0;
874
      } else {
875
876
877
878
        const int delta_ctx = prev_mbmi->delta;
        unsigned int delta = aom_read_symbol(
            r, xd->tile_ctx->lpf_delta_cdf[delta_ctx], DELTA_RANGE, ACCT_STR);
        curr_mbmi->delta = delta;
879
        delta *= LPF_STEP;
880
881

        if (delta) {
882
883
884
885
          const int sign_ctx = prev_mbmi->sign;
          const int sign = aom_read_symbol(
              r, xd->tile_ctx->lpf_sign_cdf[reuse_ctx][sign_ctx], 2, ACCT_STR);
          curr_mbmi->sign = sign;
886
887
888
          filt_lvl = sign ? prev_lvl + delta : prev_lvl - delta;
        } else {
          filt_lvl = prev_lvl;
889
          curr_mbmi->sign = 0;
890
        }
891
892
      }
    }
893
894

    av1_loop_filter_sb_level_init(cm, mi_row, mi_col, filt_lvl);
895
  }
896
897
#endif  // CONFIG_LOOPFILTER_LEVEL
#endif  // CONFIG_LPF_SB
898

899
#if CONFIG_LOOP_RESTORATION
900
  for (int plane = 0; plane < av1_num_planes(cm); ++plane) {
901
    int rcol0, rcol1, rrow0, rrow1, tile_tl_idx;
902
903
    if (av1_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize,
                                           &rcol0, &rcol1, &rrow0, &rrow1,
904
905
                                           &tile_tl_idx)) {
      const int rstride = cm->rst_info[plane].horz_units_per_tile;
906
907
      for (int rrow = rrow0; rrow < rrow1; ++rrow) {
        for (int rcol = rcol0; rcol < rcol1; ++rcol) {
908
          const int rtile_idx = tile_tl_idx + rcol + rrow * rstride;
909
910
911
912
913
914
          loop_restoration_read_sb_coeffs(cm, xd, r, plane, rtile_idx);
        }
      }
    }
  }
#endif
Jingning Han's avatar
Jingning Han committed
915
916
}

917
static void setup_bool_decoder(const uint8_t *data, const uint8_t *data_end,
Alex Converse's avatar
Alex Converse committed
918
                               const size_t read_size,
Yaowu Xu's avatar
Yaowu Xu committed
919
                               struct aom_internal_error_info *error_info,
920
                               aom_reader *r, uint8_t allow_update_cdf,
921
                               aom_decrypt_cb decrypt_cb, void *decrypt_state) {
Alex Converse's avatar
Alex Converse committed
922
923
924
925
  // Validate the calculated partition length. If the buffer
  // described by the partition can't be fully read, then restrict
  // it to the portion that can be (for EC mode) or throw an error.
  if (!read_is_valid(data, read_size, data_end))
Yaowu Xu's avatar
Yaowu Xu committed
926
    aom_internal_error(error_info, AOM_CODEC_CORRUPT_FRAME,
Alex Converse's avatar
Alex Converse committed
927
928
                       "Truncated packet or corrupt tile length");

929
  if (aom_reader_init(r, data, read_size, decrypt_cb, decrypt_state))
Yaowu Xu's avatar
Yaowu Xu committed
930
    aom_internal_error(error_info, AOM_CODEC_MEM_ERROR,
Alex Converse's avatar
Alex Converse committed
931
                       "Failed to allocate bool decoder %d", 1);
932
933

  r->allow_update_cdf = allow_update_cdf;
Alex Converse's avatar
Alex Converse committed
934
}
Jingning Han's avatar
Jingning Han committed
935

Yaowu Xu's avatar
Yaowu Xu committed
936
937
static void setup_segmentation(AV1_COMMON *const cm,
                               struct aom_read_bit_buffer *rb) {
938
  struct segmentation *const seg = &cm->seg;
Jingning Han's avatar
Jingning Han committed
939
940
941

  seg->update_map = 0;
  seg->update_data = 0;
942
  seg->temporal_update = 0;
Jingning Han's avatar
Jingning Han committed
943

Yaowu Xu's avatar
Yaowu Xu committed
944
  seg->enabled = aom_rb_read_bit(rb);
945
  if (!seg->enabled) return;
Jingning Han's avatar
Jingning Han committed
946
947

  // Segmentation map update
948
949
950
  if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
    seg->update_map = 1;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
951
    seg->update_map = aom_rb_read_bit(rb);
952
  }
Jingning Han's avatar
Jingning Han committed
953
  if (seg->update_map) {
954
955
956
    if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
      seg->temporal_update = 0;
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
957
      seg->temporal_update = aom_rb_read_bit(rb);
958
    }
Jingning Han's avatar
Jingning Han committed
959
960
  }

961
962
963
964
#if CONFIG_SPATIAL_SEGMENTATION
  cm->preskip_segid = 0;
#endif

Jingning Han's avatar
Jingning Han committed
965
  // Segmentation data update