Coverage Report

Created: 2026-10-28 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/avm/av2/decoder/decodeframe.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2021, Alliance for Open Media. All rights reserved
3
 *
4
 * This source code is subject to the terms of the BSD 3-Clause Clear License
5
 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear
6
 * License was not distributed with this source code in the LICENSE file, you
7
 * can obtain it at aomedia.org/license/software-license/bsd-3-c-c/.  If the
8
 * Alliance for Open Media Patent License 1.0 was not distributed with this
9
 * source code in the PATENTS file, you can obtain it at
10
 * aomedia.org/license/patent-license/.
11
 */
12
13
#include <assert.h>
14
#include <stdbool.h>
15
#include <stddef.h>
16
#include <string.h>
17
18
#include "av2/common/av2_common_int.h"
19
#include "av2/common/blockd.h"
20
#include "av2/common/bru.h"
21
#include "av2/common/enums.h"
22
#include "av2/common/filter.h"
23
#include "av2/common/scan.h"
24
#include "config/avm_config.h"
25
#include "config/avm_dsp_rtcd.h"
26
#include "config/avm_scale_rtcd.h"
27
#include "config/av2_rtcd.h"
28
#include "av2/common/level.h"
29
30
#include "avm/avm_codec.h"
31
#include "avm_dsp/avm_dsp_common.h"
32
#include "avm_dsp/binary_codes_reader.h"
33
#include "avm_dsp/bitreader.h"
34
#include "avm_dsp/bitreader_buffer.h"
35
#include "avm_mem/avm_mem.h"
36
#include "avm_ports/avm_timer.h"
37
#include "avm_ports/mem.h"
38
#include "avm_ports/mem_ops.h"
39
#include "avm_scale/avm_scale.h"
40
#include "avm_util/avm_thread.h"
41
42
#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
43
#include "avm_util/debug_util.h"
44
#endif  // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
45
46
#include "av2/common/alloccommon.h"
47
#include "av2/common/cdef.h"
48
49
#include "av2/common/gdf.h"
50
51
#include "av2/common/ccso.h"
52
#include "av2/common/cfl.h"
53
#if CONFIG_INSPECTION
54
#include "av2/decoder/inspection.h"
55
#endif
56
#include "av2/common/common.h"
57
#include "av2/common/entropy.h"
58
#include "av2/common/entropymode.h"
59
#include "av2/common/entropymv.h"
60
#include "av2/common/frame_buffers.h"
61
#include "av2/common/idct.h"
62
#include "av2/common/mvref_common.h"
63
#include "av2/common/pred_common.h"
64
#include "av2/common/quant_common.h"
65
#include "av2/common/reconinter.h"
66
#include "av2/common/reconintra.h"
67
#include "av2/common/resize.h"
68
#include "av2/common/seg_common.h"
69
#include "av2/common/thread_common.h"
70
#include "av2/common/tile_common.h"
71
#include "av2/common/tip.h"
72
#include "av2/common/warped_motion.h"
73
#include "av2/decoder/decodeframe.h"
74
#include "av2/decoder/decodemv.h"
75
#include "av2/decoder/decoder.h"
76
#include "av2/decoder/decodetxb.h"
77
#include "av2/decoder/detokenize.h"
78
#include "av2/decoder/obu.h"
79
80
0
#define AVM_MIN_THREADS_PER_TILE 1
81
0
#define AVM_MAX_THREADS_PER_TILE 2
82
83
#define MC_TEMP_BUF_PELS                           \
84
5.29k
  (((MAX_SB_SIZE) * 2 + (AVM_INTERP_EXTEND) * 2) * \
85
5.29k
   ((MAX_SB_SIZE) * 2 + (AVM_INTERP_EXTEND) * 2))
86
87
static void read_wienerns_framefilters_hdr(AV2_COMMON *cm, int plane,
88
                                           struct avm_read_bit_buffer *rb);
89
90
13
void copy_frame_filters_to_runits_if_needed(AV2_COMMON *cm) {
91
13
  const int num_planes = av2_num_planes(cm);
92
52
  for (int plane = 0; plane < num_planes; plane++) {
93
39
    if (!is_frame_filters_enabled(plane)) continue;
94
39
    RestorationInfo *rsi = &cm->rst_info[plane];
95
39
    if ((rsi->frame_restoration_type == RESTORE_WIENER_NONSEP ||
96
20
         rsi->frame_restoration_type == RESTORE_SWITCHABLE) &&
97
22
        rsi->frame_filters_on) {
98
9
      assert(rsi->frame_filters_initialized);
99
9
      for (int runit_idx = 0;
100
367
           runit_idx < rsi->horz_units_per_frame * rsi->vert_units_per_frame;
101
358
           ++runit_idx) {
102
358
        RestorationUnitInfo *rui = &rsi->unit_info[runit_idx];
103
358
        if (rui->restoration_type == RESTORE_WIENER_NONSEP) {
104
249
          copy_nsfilter_taps(&rui->wienerns_info, &rsi->frame_filters);
105
249
        }
106
358
      }
107
9
    }
108
39
  }
109
13
}
110
111
#if CONFIG_THROUGHPUT_ANALYSIS
112
int64_t tot_ctx_syms = { 0 };
113
int64_t tot_bypass_syms = { 0 };
114
int64_t max_ctx_syms = { 0 };
115
int64_t max_bypass_syms = { 0 };
116
int64_t max_bits = { 0 };
117
int64_t tot_bits = { 0 };
118
int64_t tot_frames = { 0 };
119
int64_t total_context_switch = { 0 };
120
int64_t total_total_hits = { 0 };
121
#endif  // CONFIG_THROUGHPUT_ANALYSIS
122
123
int av2_check_byte_alignment(AV2_COMMON *const cm,
124
4.30k
                             struct avm_read_bit_buffer *const rb) {
125
13.5k
  while (rb->bit_offset & 7) {
126
9.79k
    if (avm_rb_read_bit(rb)) {
127
575
      cm->error.error_code = AVM_CODEC_CORRUPT_FRAME;
128
575
      return -1;
129
575
    }
130
9.79k
  }
131
3.72k
  return 0;
132
4.30k
}
133
134
// Checks that the remaining bits start with a 1 and ends with 0s.
135
// It consumes an additional byte, if already byte aligned before the check.
136
23.2k
int av2_check_trailing_bits(AV2Decoder *pbi, struct avm_read_bit_buffer *rb) {
137
23.2k
  AV2_COMMON *const cm = &pbi->common;
138
  // bit_offset is set to 0 (mod 8) when the reader is already byte aligned
139
23.2k
  int bits_before_alignment = 8 - rb->bit_offset % 8;
140
23.2k
  int trailing = avm_rb_read_literal(rb, bits_before_alignment);
141
23.2k
  if (trailing != (1 << (bits_before_alignment - 1))) {
142
1.38k
    cm->error.error_code = AVM_CODEC_CORRUPT_FRAME;
143
1.38k
    return -1;
144
1.38k
  }
145
21.8k
  return 0;
146
23.2k
}
147
148
// Use only_chroma = 1 to only set the chroma planes
149
static AVM_INLINE void set_planes_to_neutral_grey(
150
    const SequenceHeader *const seq_params, const YV12_BUFFER_CONFIG *const buf,
151
0
    int only_chroma) {
152
0
  const int val = 1 << (seq_params->bit_depth - 1);
153
0
  for (int plane = only_chroma; plane < MAX_MB_PLANE; plane++) {
154
0
    const int is_uv = plane > 0;
155
0
    uint16_t *const base = buf->buffers[plane];
156
    // Set the first row to neutral grey. Then copy the first row to all
157
    // subsequent rows.
158
0
    if (buf->crop_heights[is_uv] > 0) {
159
0
      avm_memset16(base, val, buf->crop_widths[is_uv]);
160
0
      for (int row_idx = 1; row_idx < buf->crop_heights[is_uv]; row_idx++) {
161
0
        memcpy(&base[row_idx * buf->strides[is_uv]], base,
162
0
               sizeof(*base) * buf->crop_widths[is_uv]);
163
0
      }
164
0
    }
165
0
  }
166
0
}
167
168
static AVM_INLINE void loop_restoration_read_sb_coeffs(AV2_COMMON *cm,
169
                                                       MACROBLOCKD *xd,
170
                                                       avm_reader *const r,
171
                                                       int plane,
172
                                                       int runit_idx);
173
174
55.9k
static int read_is_valid(const uint8_t *start, size_t len, const uint8_t *end) {
175
55.9k
  return len != 0 && len <= (size_t)(end - start);
176
55.9k
}
177
178
static TX_MODE read_tx_mode(struct avm_read_bit_buffer *rb,
179
8.90k
                            int coded_lossless) {
180
8.90k
  if (coded_lossless) return ONLY_4X4;
181
8.60k
  return avm_rb_read_bit(rb) ? TX_MODE_SELECT : TX_MODE_LARGEST;
182
8.90k
}
183
184
static REFERENCE_MODE read_frame_reference_mode(
185
8.90k
    const AV2_COMMON *cm, struct avm_read_bit_buffer *rb) {
186
8.90k
  if (frame_is_intra_only(cm)) {
187
8.90k
    return SINGLE_REFERENCE;
188
8.90k
  } else {
189
0
    return avm_rb_read_bit(rb) ? REFERENCE_MODE_SELECT : SINGLE_REFERENCE;
190
0
  }
191
8.90k
}
192
193
static AVM_INLINE void inverse_transform_block(DecoderCodingBlock *dcb,
194
                                               const AV2_COMMON *cm, int plane,
195
                                               const TX_TYPE tx_type,
196
                                               const TX_SIZE tx_size,
197
                                               uint16_t *dst, int stride,
198
1.98M
                                               int reduced_tx_set) {
199
1.98M
  tran_low_t *dqcoeff = dcb->dqcoeff_block[plane] + dcb->cb_offset[plane];
200
1.98M
  eob_info *eob_data = dcb->eob_data[plane] + dcb->txb_offset[plane];
201
1.98M
  uint16_t scan_line = eob_data->max_scan_line;
202
1.98M
  uint16_t eob = eob_data->eob;
203
  // Update eob and scan_line according to those of the other chroma plane
204
1.98M
  if (plane && is_cctx_allowed(cm, &dcb->xd)) {
205
211k
    eob_info *eob_data_c1 =
206
211k
        dcb->eob_data[AVM_PLANE_U] + dcb->txb_offset[AVM_PLANE_U];
207
211k
    eob_info *eob_data_c2 =
208
211k
        dcb->eob_data[AVM_PLANE_V] + dcb->txb_offset[AVM_PLANE_V];
209
211k
    scan_line = AVMMAX(eob_data_c1->max_scan_line, eob_data_c2->max_scan_line);
210
211k
    eob = AVMMAX(eob_data_c1->eob, eob_data_c2->eob);
211
211k
  }
212
1.98M
  av2_inverse_transform_block(
213
1.98M
      &dcb->xd, dqcoeff, plane, tx_type, tx_size, dst, stride, eob,
214
1.98M
      replace_adst_by_ddt(cm->seq_params.enable_inter_ddt,
215
1.98M
                          cm->features.allow_screen_content_tools, &dcb->xd),
216
1.98M
      reduced_tx_set);
217
1.98M
  const int width = tx_size_wide[tx_size] <= 32 ? tx_size_wide[tx_size] : 32;
218
1.98M
  const int height = tx_size_high[tx_size] <= 32 ? tx_size_high[tx_size] : 32;
219
1.98M
  const int sbSize = (width >= 8 && height >= 8) ? 8 : 4;
220
1.98M
  int32_t nz0 = (sbSize - 1) * tx_size_wide[tx_size] + sbSize;
221
1.98M
  int32_t nz1 = (scan_line + 1);
222
1.98M
  memset(dqcoeff, 0, AVMMAX(nz0, nz1) * sizeof(dqcoeff[0]));
223
1.98M
}
224
225
static AVM_INLINE void read_coeffs_tx_intra_block(
226
    const AV2_COMMON *const cm, DecoderCodingBlock *dcb, avm_reader *const r,
227
4.46M
    const int plane, const int row, const int col, const TX_SIZE tx_size) {
228
4.46M
  MB_MODE_INFO *mbmi = dcb->xd.mi[0];
229
4.46M
  if (!mbmi->skip_txfm[dcb->xd.tree_type == CHROMA_PART]) {
230
#if TXCOEFF_TIMER
231
    struct avm_usec_timer timer;
232
    avm_usec_timer_start(&timer);
233
#endif
234
4.46M
    av2_read_coeffs_txb_facade(cm, dcb, r, plane, row, col, tx_size);
235
#if TXCOEFF_TIMER
236
    avm_usec_timer_mark(&timer);
237
    const int64_t elapsed_time = avm_usec_timer_elapsed(&timer);
238
    cm->txcoeff_timer += elapsed_time;
239
    ++cm->txb_count;
240
#endif
241
4.46M
  } else {
242
    // all tx blocks are skipped.
243
14
    av2_update_txk_skip_array(cm, dcb->xd.mi_row, dcb->xd.mi_col,
244
14
                              dcb->xd.tree_type, &mbmi->chroma_ref_info, plane,
245
14
                              row, col, tx_size);
246
14
  }
247
4.46M
}
248
249
static AVM_INLINE void decode_block_void(const AV2_COMMON *const cm,
250
                                         DecoderCodingBlock *dcb,
251
                                         avm_reader *const r, const int plane,
252
                                         const int row, const int col,
253
0
                                         const TX_SIZE tx_size) {
254
0
  (void)cm;
255
0
  (void)dcb;
256
0
  (void)r;
257
0
  (void)plane;
258
0
  (void)row;
259
0
  (void)col;
260
0
  (void)tx_size;
261
0
}
262
263
static AVM_INLINE void predict_inter_block_void(AV2_COMMON *const cm,
264
                                                DecoderCodingBlock *dcb,
265
0
                                                BLOCK_SIZE bsize) {
266
0
  (void)cm;
267
0
  (void)dcb;
268
0
  (void)bsize;
269
0
}
270
271
static AVM_INLINE void predict_and_reconstruct_intra_block(
272
    const AV2_COMMON *const cm, DecoderCodingBlock *dcb, avm_reader *const r,
273
4.44M
    const int plane, const int row, const int col, const TX_SIZE tx_size) {
274
4.44M
  (void)r;
275
4.44M
  MACROBLOCKD *const xd = &dcb->xd;
276
4.44M
  MB_MODE_INFO *mbmi = xd->mi[0];
277
4.44M
  PLANE_TYPE plane_type = get_plane_type(plane);
278
279
4.44M
  av2_predict_intra_block_facade(cm, xd, plane, col, row, tx_size);
280
#if CONFIG_INSPECTION
281
  {
282
    const int txwpx = tx_size_wide[tx_size];
283
    const int txhpx = tx_size_high[tx_size];
284
285
    struct macroblockd_plane *const pd = &xd->plane[plane];
286
    const int dst_stride = pd->dst.stride;
287
    uint16_t *dst = &pd->dst.buf[(row * dst_stride + col) << MI_SIZE_LOG2];
288
    for (int i = 0; i < txhpx; i++) {
289
      for (int j = 0; j < txwpx; j++) {
290
        uint16_t pixel = dst[i * dst_stride + j];
291
        int stride = cm->predicted_pixels.strides[plane > 0];
292
        int pixel_c, pixel_r;
293
294
        if (plane) {
295
          mi_to_pixel_loc(&pixel_c, &pixel_r,
296
                          mbmi->chroma_ref_info.mi_col_chroma_base,
297
                          mbmi->chroma_ref_info.mi_row_chroma_base, col, row,
298
                          pd->subsampling_x, pd->subsampling_y);
299
        } else {
300
          mi_to_pixel_loc(&pixel_c, &pixel_r, xd->mi_col, xd->mi_row, col, row,
301
                          pd->subsampling_x, pd->subsampling_y);
302
        }
303
304
        pixel_c += j;
305
        pixel_r += i;
306
        cm->predicted_pixels.buffers[plane][pixel_r * stride + pixel_c] = pixel;
307
      }
308
    }
309
  }
310
#endif  // CONFIG_INSPECTION
311
312
#if CONFIG_MISMATCH_DEBUG
313
  const int mi_row = -xd->mb_to_top_edge >> (3 + MI_SIZE_LOG2);
314
  const int mi_col = -xd->mb_to_left_edge >> (3 + MI_SIZE_LOG2);
315
  int pixel_c, pixel_r;
316
  const int blk_w = tx_size_wide[tx_size];
317
  const int blk_h = tx_size_high[tx_size];
318
  if (plane == 0 || xd->is_chroma_ref) {
319
    struct macroblockd_plane *const pd = &xd->plane[plane];
320
    if (plane) {
321
      mi_to_pixel_loc(&pixel_c, &pixel_r,
322
                      mbmi->chroma_ref_info.mi_col_chroma_base,
323
                      mbmi->chroma_ref_info.mi_row_chroma_base, col, row,
324
                      pd->subsampling_x, pd->subsampling_y);
325
    } else {
326
      mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, col, row,
327
                      pd->subsampling_x, pd->subsampling_y);
328
    }
329
    int pixels_c = (cm->mi_params.mi_cols * MI_SIZE) >> pd->subsampling_x;
330
    int pixels_r = (cm->mi_params.mi_rows * MI_SIZE) >> pd->subsampling_y;
331
    mismatch_check_block_pre(pd->dst.buf, pd->dst.stride,
332
                             cm->current_frame.display_order_hint, pixels_c,
333
                             pixels_r, plane, pixel_c, pixel_r, blk_w, blk_h);
334
  }
335
#endif  // CONFIG_MISMATCH_DEBUG
336
337
4.48M
  if (!mbmi->skip_txfm[xd->tree_type == CHROMA_PART]) {
338
4.48M
    eob_info *eob_data = dcb->eob_data[plane] + dcb->txb_offset[plane];
339
    // In CCTX, when C2 eob = 0 but C1 eob > 0, plane V reconstruction is
340
    // still needed
341
4.48M
    int recon_with_cctx = 0;
342
4.48M
    if (is_cctx_allowed(cm, xd) && plane == AVM_PLANE_V &&
343
590k
        av2_get_cctx_type(xd, row, col) > CCTX_NONE) {
344
27.4k
      eob_info *eob_data_c1 =
345
27.4k
          dcb->eob_data[AVM_PLANE_U] + dcb->txb_offset[AVM_PLANE_U];
346
27.4k
      recon_with_cctx = eob_data_c1->eob > 0;
347
27.4k
    }
348
4.48M
    if (eob_data->eob || recon_with_cctx) {
349
1.94M
      const uint8_t reduced_tx_set_used =
350
1.94M
          is_reduced_tx_set_used(cm, plane_type);
351
      // tx_type was read out in av2_read_coeffs_txb.
352
1.94M
      const TX_TYPE tx_type = av2_get_tx_type(xd, plane_type, row, col, tx_size,
353
1.94M
                                              reduced_tx_set_used);
354
1.94M
      struct macroblockd_plane *const pd = &xd->plane[plane];
355
1.94M
      uint16_t *dst =
356
1.94M
          &pd->dst.buf[(row * pd->dst.stride + col) << MI_SIZE_LOG2];
357
1.94M
      inverse_transform_block(dcb, cm, plane, tx_type, tx_size, dst,
358
1.94M
                              pd->dst.stride, reduced_tx_set_used);
359
1.94M
    }
360
4.48M
  }
361
362
#if CONFIG_MISMATCH_DEBUG
363
  {
364
    struct macroblockd_plane *const pd = &xd->plane[plane];
365
    uint16_t *dst = &pd->dst.buf[(row * pd->dst.stride + col) << MI_SIZE_LOG2];
366
    if (plane) {
367
      mi_to_pixel_loc(&pixel_c, &pixel_r,
368
                      mbmi->chroma_ref_info.mi_col_chroma_base,
369
                      mbmi->chroma_ref_info.mi_row_chroma_base, col, row,
370
                      pd->subsampling_x, pd->subsampling_y);
371
    } else {
372
      mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, col, row,
373
                      pd->subsampling_x, pd->subsampling_y);
374
    }
375
    int pixels_c = (cm->mi_params.mi_cols * MI_SIZE) >> pd->subsampling_x;
376
    int pixels_r = (cm->mi_params.mi_rows * MI_SIZE) >> pd->subsampling_y;
377
    mismatch_check_block_tx(dst, pd->dst.stride,
378
                            cm->current_frame.display_order_hint, pixels_c,
379
                            pixels_r, plane, pixel_c, pixel_r, blk_w, blk_h);
380
  }
381
#endif  // CONFIG_MISMATCH_DEBUG
382
4.44M
}
383
384
// Facade function for inverse cross chroma component transform
385
static AVM_INLINE void inverse_cross_chroma_transform_block(
386
    const AV2_COMMON *const cm, DecoderCodingBlock *dcb, avm_reader *const r,
387
    const int plane, const int blk_row, const int blk_col,
388
601k
    const TX_SIZE tx_size) {
389
601k
  (void)cm;
390
601k
  (void)r;
391
601k
  (void)plane;
392
601k
  tran_low_t *dqcoeff_c1 =
393
601k
      dcb->dqcoeff_block[AVM_PLANE_U] + dcb->cb_offset[AVM_PLANE_U];
394
601k
  tran_low_t *dqcoeff_c2 =
395
601k
      dcb->dqcoeff_block[AVM_PLANE_V] + dcb->cb_offset[AVM_PLANE_V];
396
601k
  MACROBLOCKD *const xd = &dcb->xd;
397
601k
  const CctxType cctx_type = av2_get_cctx_type(xd, blk_row, blk_col);
398
601k
  av2_inv_cross_chroma_tx_block(dqcoeff_c1, dqcoeff_c2, tx_size, cctx_type,
399
601k
                                xd->bd);
400
601k
}
401
402
static AVM_INLINE void inverse_transform_inter_block(
403
    const AV2_COMMON *const cm, DecoderCodingBlock *dcb, avm_reader *const r,
404
    const int plane, const int blk_row, const int blk_col,
405
50.5k
    const TX_SIZE tx_size) {
406
50.5k
  (void)r;
407
50.5k
  MACROBLOCKD *const xd = &dcb->xd;
408
50.5k
  PLANE_TYPE plane_type = get_plane_type(plane);
409
50.5k
  const struct macroblockd_plane *const pd = &xd->plane[plane];
410
50.5k
  const uint8_t reduced_tx_set_used = is_reduced_tx_set_used(cm, plane_type);
411
  // tx_type was read out in av2_read_coeffs_txb.
412
50.5k
  const TX_TYPE tx_type = av2_get_tx_type(xd, plane_type, blk_row, blk_col,
413
50.5k
                                          tx_size, reduced_tx_set_used);
414
415
50.5k
  uint16_t *dst =
416
50.5k
      &pd->dst.buf[(blk_row * pd->dst.stride + blk_col) << MI_SIZE_LOG2];
417
50.5k
  inverse_transform_block(dcb, cm, plane, tx_type, tx_size, dst, pd->dst.stride,
418
50.5k
                          reduced_tx_set_used);
419
#if CONFIG_MISMATCH_DEBUG
420
  int pixel_c, pixel_r;
421
  const int blk_w = tx_size_wide[tx_size];
422
  const int blk_h = tx_size_high[tx_size];
423
  const int mi_row = -xd->mb_to_top_edge >> (3 + MI_SIZE_LOG2);
424
  const int mi_col = -xd->mb_to_left_edge >> (3 + MI_SIZE_LOG2);
425
  if (plane) {
426
    MB_MODE_INFO *const mbmi = xd->mi[0];
427
    mi_to_pixel_loc(&pixel_c, &pixel_r,
428
                    mbmi->chroma_ref_info.mi_col_chroma_base,
429
                    mbmi->chroma_ref_info.mi_row_chroma_base, blk_col, blk_row,
430
                    pd->subsampling_x, pd->subsampling_y);
431
  } else {
432
    mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, blk_col, blk_row,
433
                    pd->subsampling_x, pd->subsampling_y);
434
  }
435
  int pixels_c = (cm->mi_params.mi_cols * MI_SIZE) >> pd->subsampling_x;
436
  int pixels_r = (cm->mi_params.mi_rows * MI_SIZE) >> pd->subsampling_y;
437
  mismatch_check_block_tx(dst, pd->dst.stride,
438
                          cm->current_frame.display_order_hint, pixels_c,
439
                          pixels_r, plane, pixel_c, pixel_r, blk_w, blk_h);
440
#endif  // CONFIG_MISMATCH_DEBUG
441
50.5k
}
442
443
static AVM_INLINE void set_cb_buffer_offsets(DecoderCodingBlock *dcb,
444
4.51M
                                             TX_SIZE tx_size, int plane) {
445
4.51M
  dcb->cb_offset[plane] += tx_size_wide[tx_size] * tx_size_high[tx_size];
446
4.51M
  dcb->txb_offset[plane] =
447
4.51M
      dcb->cb_offset[plane] / (TX_SIZE_W_MIN * TX_SIZE_H_MIN);
448
4.51M
}
449
450
static AVM_INLINE void decode_reconstruct_tx(
451
    AV2_COMMON *cm, ThreadData *const td, avm_reader *r,
452
    MB_MODE_INFO *const mbmi, int plane, BLOCK_SIZE plane_bsize, int blk_row,
453
49.6k
    int blk_col, TX_SIZE tx_size, int *eob_total) {
454
49.6k
  DecoderCodingBlock *const dcb = &td->dcb;
455
49.6k
  MACROBLOCKD *const xd = &dcb->xd;
456
49.6k
  if (plane == AVM_PLANE_U && is_cctx_allowed(cm, xd)) return;
457
38.1k
  int txp_index = av2_get_txb_size_index(plane_bsize, blk_row, blk_col);
458
  // Scale to match transform block unit.
459
38.1k
  const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
460
38.1k
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
461
462
38.1k
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
463
464
38.1k
  if (mbmi->tx_partition_type[txp_index] == TX_PARTITION_NONE || plane) {
465
37.7k
    if (plane == AVM_PLANE_V && is_cctx_allowed(cm, xd)) {
466
11.4k
      td->read_coeffs_tx_inter_block_visit(cm, dcb, r, AVM_PLANE_U, blk_row,
467
11.4k
                                           blk_col, tx_size);
468
11.4k
      td->read_coeffs_tx_inter_block_visit(cm, dcb, r, AVM_PLANE_V, blk_row,
469
11.4k
                                           blk_col, tx_size);
470
11.4k
      td->inverse_cctx_block_visit(cm, dcb, r, -1, blk_row, blk_col, tx_size);
471
11.4k
      td->inverse_tx_inter_block_visit(cm, dcb, r, AVM_PLANE_U, blk_row,
472
11.4k
                                       blk_col, tx_size);
473
11.4k
      td->inverse_tx_inter_block_visit(cm, dcb, r, AVM_PLANE_V, blk_row,
474
11.4k
                                       blk_col, tx_size);
475
11.4k
      eob_info *eob_data_c1 =
476
11.4k
          dcb->eob_data[AVM_PLANE_U] + dcb->txb_offset[AVM_PLANE_U];
477
11.4k
      eob_info *eob_data_c2 =
478
11.4k
          dcb->eob_data[AVM_PLANE_V] + dcb->txb_offset[AVM_PLANE_V];
479
11.4k
      *eob_total += eob_data_c1->eob + eob_data_c2->eob;
480
11.4k
      set_cb_buffer_offsets(dcb, tx_size, AVM_PLANE_U);
481
11.4k
      set_cb_buffer_offsets(dcb, tx_size, AVM_PLANE_V);
482
26.2k
    } else {
483
26.2k
      assert(plane == AVM_PLANE_Y || !is_cctx_allowed(cm, xd));
484
26.2k
      td->read_coeffs_tx_inter_block_visit(cm, dcb, r, plane, blk_row, blk_col,
485
26.2k
                                           tx_size);
486
487
26.2k
      td->inverse_tx_inter_block_visit(cm, dcb, r, plane, blk_row, blk_col,
488
26.2k
                                       tx_size);
489
26.2k
      eob_info *eob_data = dcb->eob_data[plane] + dcb->txb_offset[plane];
490
26.2k
      *eob_total += eob_data->eob;
491
26.2k
      set_cb_buffer_offsets(dcb, tx_size, plane);
492
26.2k
    }
493
37.7k
  } else {
494
335
    get_tx_partition_sizes(mbmi->tx_partition_type[txp_index], tx_size,
495
335
                           &mbmi->txb_pos, mbmi->sub_txs, xd->error_info);
496
497
1.60k
    for (int txb_idx = 0; txb_idx < mbmi->txb_pos.n_partitions; ++txb_idx) {
498
1.27k
      mbmi->txb_idx = 0;
499
1.27k
      const TX_SIZE sub_tx = mbmi->sub_txs[txb_idx];
500
1.27k
      const int offsetr = blk_row + mbmi->txb_pos.row_offset[txb_idx];
501
1.27k
      const int offsetc = blk_col + mbmi->txb_pos.col_offset[txb_idx];
502
1.27k
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
503
504
1.27k
      td->read_coeffs_tx_inter_block_visit(cm, dcb, r, plane, offsetr, offsetc,
505
1.27k
                                           sub_tx);
506
1.27k
      td->inverse_tx_inter_block_visit(cm, dcb, r, plane, offsetr, offsetc,
507
1.27k
                                       sub_tx);
508
1.27k
      eob_info *eob_data = dcb->eob_data[plane] + dcb->txb_offset[plane];
509
1.27k
      *eob_total += eob_data->eob;
510
1.27k
      set_cb_buffer_offsets(dcb, sub_tx, plane);
511
1.27k
    }
512
335
  }
513
38.1k
}
514
515
static AVM_INLINE void set_offsets(AV2_COMMON *const cm, MACROBLOCKD *const xd,
516
                                   BLOCK_SIZE bsize, int mi_row, int mi_col,
517
                                   int bw, int bh, int x_inside_boundary,
518
                                   int y_inside_boundary,
519
1.14M
                                   PARTITION_TREE *parent, int index) {
520
1.14M
  const int num_planes = av2_num_planes(cm);
521
1.14M
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
522
1.14M
  const TileInfo *const tile = &xd->tile;
523
524
1.14M
  set_mi_offsets(mi_params, xd, mi_row, mi_col, x_inside_boundary,
525
1.14M
                 y_inside_boundary);
526
1.14M
  xd->mi[0]->sb_type[xd->tree_type == CHROMA_PART] = bsize;
527
1.14M
  if (xd->tree_type != CHROMA_PART) {
528
968k
    xd->mi[0]->mi_row_start = mi_row;
529
968k
    xd->mi[0]->mi_col_start = mi_col;
530
968k
  }
531
#if CONFIG_RD_DEBUG
532
  xd->mi[0]->mi_row = mi_row;
533
  xd->mi[0]->mi_col = mi_col;
534
#endif
535
536
1.14M
  if (xd->tree_type == SHARED_PART) {
537
634k
    assert(x_inside_boundary && y_inside_boundary);
538
4.69M
    for (int x = 1; x < x_inside_boundary; ++x) xd->mi[x] = xd->mi[0];
539
634k
    int idx = mi_params->mi_stride;
540
4.52M
    for (int y = 1; y < y_inside_boundary; ++y) {
541
3.89M
      memcpy(&xd->mi[idx], &xd->mi[0], x_inside_boundary * sizeof(xd->mi[0]));
542
3.89M
      idx += mi_params->mi_stride;
543
3.89M
    }
544
634k
  }
545
546
1.14M
  CHROMA_REF_INFO *chroma_ref_info = &xd->mi[0]->chroma_ref_info;
547
1.14M
  set_chroma_ref_info(xd->tree_type, mi_row, mi_col, index, bsize,
548
1.14M
                      chroma_ref_info, parent ? &parent->chroma_ref_info : NULL,
549
1.14M
                      parent ? parent->bsize : BLOCK_INVALID,
550
1.14M
                      parent ? parent->partition : PARTITION_NONE,
551
1.14M
                      xd->plane[1].subsampling_x, xd->plane[1].subsampling_y);
552
1.14M
  set_plane_n4(xd, bw, bh, num_planes, chroma_ref_info);
553
1.14M
  set_entropy_context(xd, mi_row, mi_col, num_planes, chroma_ref_info);
554
555
  // Distance of Mb to the various image edges. These are specified to 8th pel
556
  // as they are always compared to values that are in 1/8th pel units
557
1.14M
  set_mi_row_col(cm, xd, tile, mi_row, bh, mi_col, bw, mi_params->mi_rows,
558
1.14M
                 mi_params->mi_cols, chroma_ref_info);
559
1.14M
  xd->mi[0]->chroma_mi_row_start = mi_row;
560
1.14M
  xd->mi[0]->chroma_mi_col_start = mi_col;
561
562
1.14M
  av2_setup_dst_planes(xd->plane, &cm->cur_frame->buf, mi_row, mi_col, 0,
563
1.14M
                       num_planes, chroma_ref_info);
564
1.14M
}
565
566
static INLINE void extend_mc_border(const struct scale_factors *const sf,
567
                                    struct buf_2d *const pre_buf,
568
                                    MV32 scaled_mv, PadBlock block,
569
                                    int subpel_x_mv, int subpel_y_mv,
570
                                    int do_warp, int is_intrabc,
571
                                    uint16_t *mc_buf, uint16_t **pre,
572
130k
                                    int *src_stride) {
573
130k
  int x_pad = 0, y_pad = 0;
574
130k
  if (update_extend_mc_border_params(sf, pre_buf, scaled_mv, &block,
575
130k
                                     subpel_x_mv, subpel_y_mv, do_warp,
576
130k
                                     is_intrabc, &x_pad, &y_pad, NULL)) {
577
    // Get reference block pointer.
578
0
    const uint16_t *const buf_ptr =
579
0
        pre_buf->buf0 + block.y0 * pre_buf->stride + block.x0;
580
0
    int buf_stride = pre_buf->stride;
581
0
    const int b_w = block.x1 - block.x0;
582
0
    const int b_h = block.y1 - block.y0;
583
584
    // Extend the border.
585
0
    highbd_build_mc_border(buf_ptr, buf_stride, mc_buf, b_w, block.x0, block.y0,
586
0
                           b_w, b_h, pre_buf->width, pre_buf->height);
587
588
0
    *src_stride = b_w;
589
0
    *pre = mc_buf + y_pad * (AVM_INTERP_EXTEND - 1) * b_w +
590
0
           x_pad * (AVM_INTERP_EXTEND - 1);
591
0
  }
592
130k
}
593
static void dec_calc_subpel_params_and_extend(
594
    const MV *const src_mv, InterPredParams *const inter_pred_params,
595
    MACROBLOCKD *const xd, int mi_x, int mi_y, int ref,
596
    int use_optflow_refinement, uint16_t **mc_buf, uint16_t **pre,
597
130k
    SubpelParams *subpel_params, int *src_stride) {
598
130k
  if (inter_pred_params->use_ref_padding) {
599
0
    common_calc_subpel_params_and_extend(
600
0
        src_mv, inter_pred_params, xd, mi_x, mi_y, ref, use_optflow_refinement,
601
0
        mc_buf, pre, subpel_params, src_stride);
602
0
    return;
603
0
  }
604
605
130k
  PadBlock block;
606
130k
  MV32 scaled_mv;
607
130k
  int subpel_x_mv, subpel_y_mv;
608
130k
  dec_calc_subpel_params(
609
130k
      src_mv, inter_pred_params, xd, mi_x, mi_y, pre, subpel_params, src_stride,
610
130k
      &block, use_optflow_refinement, &scaled_mv, &subpel_x_mv, &subpel_y_mv);
611
130k
  extend_mc_border(inter_pred_params->scale_factors,
612
130k
                   &inter_pred_params->ref_frame_buf, scaled_mv, block,
613
130k
                   subpel_x_mv, subpel_y_mv,
614
130k
                   inter_pred_params->mode == WARP_PRED,
615
130k
                   inter_pred_params->is_intrabc, mc_buf[ref], pre, src_stride);
616
130k
}
617
618
// Allocate and copy data for TIP multi threading.
619
0
static void copy_tip_worker_data(AV2Decoder *pbi, AV2_COMMON *cm) {
620
0
  int num_worker = pbi->max_threads;
621
0
  avm_free(pbi->tip_worker_data);
622
0
  CHECK_MEM_ERROR(
623
0
      cm, pbi->tip_worker_data,
624
0
      avm_memalign(32, num_worker * sizeof(*(pbi->tip_worker_data))));
625
626
0
  for (int worker_idx = 0; worker_idx < num_worker; ++worker_idx) {
627
0
    DecWorkerData *const thread_data = pbi->thread_data + worker_idx;
628
0
    TIPWorkerData *const tip_worker_data = pbi->tip_worker_data + worker_idx;
629
0
    tip_worker_data->xd = pbi->dcb.xd;
630
0
    tip_worker_data->mc_buf[0] = thread_data->td->mc_buf[0];
631
0
    tip_worker_data->mc_buf[1] = thread_data->td->mc_buf[1];
632
0
    tip_worker_data->tmp_conv_dst = thread_data->td->tmp_conv_dst;
633
    // Temporary buffers used during the SMVR and OPFL processing.
634
0
    tip_worker_data->xd.opfl_vxy_bufs = thread_data->td->opfl_vxy_bufs;
635
0
    tip_worker_data->xd.opfl_gxy_bufs = thread_data->td->opfl_gxy_bufs;
636
0
    tip_worker_data->xd.opfl_dst_bufs = thread_data->td->opfl_dst_bufs;
637
0
  }
638
0
}
639
640
static void av2_dec_setup_tip_frame(AV2Decoder *pbi, AV2_COMMON *cm,
641
0
                                    MACROBLOCKD *xd) {
642
0
  av2_setup_tip_motion_field(cm);
643
0
  if (pbi->num_workers > 1) {
644
0
    copy_tip_worker_data(pbi, cm);
645
0
    av2_setup_tip_frame_mt(cm, dec_calc_subpel_params_and_extend,
646
0
                           1 /* copy_refined_mvs */, pbi->tile_workers,
647
0
                           pbi->num_workers, &pbi->tip_sync,
648
0
                           pbi->tip_worker_data);
649
0
  } else {
650
0
    xd->opfl_vxy_bufs = pbi->td.opfl_vxy_bufs;
651
0
    xd->opfl_gxy_bufs = pbi->td.opfl_gxy_bufs;
652
0
    xd->opfl_dst_bufs = pbi->td.opfl_dst_bufs;
653
0
    av2_setup_tip_frame(cm, xd, pbi->td.mc_buf, pbi->td.tmp_conv_dst,
654
0
                        dec_calc_subpel_params_and_extend,
655
0
                        1 /* copy_refined_mvs */
656
0
    );
657
0
  }
658
659
0
  if (cm->seq_params.enable_tip_explicit_qp == 0) {
660
0
    const int avg_u_ac_delta_q =
661
0
        (cm->tip_ref.ref_frame_buffer[0]->u_ac_delta_q +
662
0
         cm->tip_ref.ref_frame_buffer[1]->u_ac_delta_q + 1) >>
663
0
        1;
664
0
    const int avg_v_ac_delta_q =
665
0
        (cm->tip_ref.ref_frame_buffer[0]->v_ac_delta_q +
666
0
         cm->tip_ref.ref_frame_buffer[1]->v_ac_delta_q + 1) >>
667
0
        1;
668
0
    const int base_qindex =
669
0
        (cm->tip_ref.ref_frame_buffer[0]->base_qindex +
670
0
         cm->tip_ref.ref_frame_buffer[1]->base_qindex + 1) >>
671
0
        1;
672
0
    cm->cur_frame->base_qindex = cm->quant_params.base_qindex = base_qindex;
673
0
    cm->cur_frame->u_ac_delta_q = cm->quant_params.u_ac_delta_q =
674
0
        avg_u_ac_delta_q;
675
0
    cm->cur_frame->v_ac_delta_q = cm->quant_params.v_ac_delta_q =
676
0
        avg_v_ac_delta_q;
677
0
  }
678
0
  if (cm->seq_params.enable_lf_sub_pu && cm->features.allow_lf_sub_pu) {
679
0
    init_tip_lf_parameter(cm, 0, av2_num_planes(cm));
680
0
    loop_filter_tip_frame(cm, xd, 0, av2_num_planes(cm));
681
0
  }
682
0
}
683
684
static AVM_INLINE void decode_mbmi_block(AV2Decoder *const pbi,
685
                                         DecoderCodingBlock *dcb, int mi_row,
686
                                         int mi_col, avm_reader *r,
687
                                         PARTITION_TYPE partition,
688
                                         BLOCK_SIZE bsize,
689
1.14M
                                         PARTITION_TREE *parent, int index) {
690
1.14M
  AV2_COMMON *const cm = &pbi->common;
691
1.14M
  const int bw = mi_size_wide[bsize];
692
1.14M
  const int bh = mi_size_high[bsize];
693
1.14M
  const int x_mis = AVMMIN(bw, cm->mi_params.mi_cols - mi_col);
694
1.14M
  const int y_mis = AVMMIN(bh, cm->mi_params.mi_rows - mi_row);
695
1.14M
  MACROBLOCKD *const xd = &dcb->xd;
696
697
#if CONFIG_ACCOUNTING
698
  avm_accounting_set_context(&pbi->accounting, mi_col, mi_row, xd->tree_type);
699
#endif
700
1.14M
  set_offsets(cm, xd, bsize, mi_row, mi_col, bw, bh, x_mis, y_mis, parent,
701
1.14M
              index);
702
1.14M
  xd->mi[0]->partition = partition;
703
  // set region_type for each mbmi
704
1.14M
  xd->mi[0]->region_type = parent->region_type;
705
  // set tree_type for each mbmi
706
1.14M
  xd->mi[0]->tree_type = xd->tree_type;
707
1.14M
  xd->mi[0]->sb_root_partition_info = parent->sb_root_partition_info;
708
1.14M
  xd->mi[0]->local_rest_type =
709
1.14M
      1;  // set non zero default type, it is only matter 1 or 0 in SW
710
1.14M
  xd->mi[0]->local_ccso_blk_flag =
711
1.14M
      1;  // set non zero default type, it is only matter 1 or 0 in SW
712
1.14M
  xd->mi[0]->local_gdf_mode =
713
1.14M
      1;  // set non zero default type, it is only matter 1 or 0 in SW
714
1.14M
  if (!bru_is_sb_active(cm, mi_col, mi_row) ||
715
1.14M
      cm->bridge_frame_info.is_bridge_frame) {
716
0
    xd->mi[0]->sb_active_mode = xd->sbi->sb_active_mode;
717
0
    bru_set_default_inter_mb_mode_info(cm, xd, xd->mi[0], bsize);
718
0
    const int w = mi_size_wide[cm->seq_params.sb_size];
719
0
    const int h = mi_size_high[cm->seq_params.sb_size];
720
0
    const int x_inside_boundary = AVMMIN(w, cm->mi_params.mi_cols - mi_col);
721
0
    const int y_inside_boundary = AVMMIN(h, cm->mi_params.mi_rows - mi_row);
722
0
    if (cm->bridge_frame_info.is_bridge_frame) {
723
0
      bru_zero_sb_mvs(cm, -1, mi_row, mi_col, x_inside_boundary,
724
0
                      y_inside_boundary);
725
0
    } else if (pbi->bru_opt_mode && cm->bru.enabled) {
726
      // only update ref MVS for optimized decoder
727
0
      bru_zero_sb_mvs(cm, cm->bru.update_ref_idx, mi_row, mi_col,
728
0
                      x_inside_boundary, y_inside_boundary);
729
0
    }
730
0
    if (!cm->bru.frame_inactive_flag &&
731
0
        !cm->bridge_frame_info.is_bridge_frame) {
732
0
      if (xd->tree_type != CHROMA_PART) {
733
0
        read_gdf(cm, r, xd);
734
0
      }
735
0
      if (cm->seq_params.enable_ccso && xd->tree_type != CHROMA_PART) {
736
0
        read_ccso(cm, r, xd);
737
0
      }
738
0
    }
739
0
  } else
740
1.14M
    av2_read_mode_info(pbi, dcb, r, x_mis, y_mis);
741
742
1.14M
  if (xd->tree_type != LUMA_PART) {
743
807k
    const struct macroblockd_plane *const pd_u = &xd->plane[1];
744
807k
    const BLOCK_SIZE chroma_bsize_base =
745
807k
        get_bsize_base(xd, xd->mi[0], AVM_PLANE_U);
746
807k
    assert(chroma_bsize_base < BLOCK_SIZES_ALL);
747
807k
    if (get_plane_block_size(chroma_bsize_base, pd_u->subsampling_x,
748
807k
                             pd_u->subsampling_y) == BLOCK_INVALID) {
749
0
      avm_internal_error(xd->error_info, AVM_CODEC_CORRUPT_FRAME,
750
0
                         "Block size %dx%d invalid with this subsampling mode",
751
0
                         block_size_wide[chroma_bsize_base],
752
0
                         block_size_high[chroma_bsize_base]);
753
0
    }
754
807k
  }
755
1.14M
}
756
757
static void dec_build_inter_predictors(const AV2_COMMON *cm,
758
                                       DecoderCodingBlock *dcb, int plane,
759
                                       MB_MODE_INFO *mi, int bw, int bh,
760
                                       int mi_x, int mi_y,
761
130k
                                       int build_for_refine_mv_only) {
762
130k
  av2_build_inter_predictors(cm, &dcb->xd, plane, mi, NULL,
763
130k
                             build_for_refine_mv_only, 1 /* build_for_decode */,
764
130k
                             bw, bh, mi_x, mi_y, dcb->mc_buf,
765
130k
                             dec_calc_subpel_params_and_extend);
766
130k
}
767
768
static AVM_INLINE void dec_build_inter_predictor(const AV2_COMMON *cm,
769
                                                 DecoderCodingBlock *dcb,
770
                                                 int mi_row, int mi_col,
771
64.0k
                                                 BLOCK_SIZE bsize) {
772
64.0k
  MACROBLOCKD *const xd = &dcb->xd;
773
64.0k
  const int num_planes = av2_num_planes(cm);
774
64.0k
  MB_MODE_INFO *mbmi = xd->mi[0];
775
776
64.0k
  int need_subblock_mvs = xd->is_chroma_ref && mbmi->refinemv_flag &&
777
0
                          !is_intrabc_block(mbmi, xd->tree_type);
778
64.0k
  assert(IMPLIES(need_subblock_mvs, !is_interintra_pred(mbmi)));
779
64.0k
  if (need_subblock_mvs && default_refinemv_modes(mbmi))
780
0
    need_subblock_mvs &= (mbmi->comp_group_idx == 0 &&
781
0
                          mbmi->interinter_comp.type == COMPOUND_AVERAGE);
782
64.0k
  if (need_subblock_mvs) {
783
0
    fill_subblock_refine_mv(xd->refinemv_subinfo, xd->plane[0].width,
784
0
                            xd->plane[0].height, mbmi->mv[0].as_mv,
785
0
                            mbmi->mv[1].as_mv);
786
0
  }
787
788
195k
  for (int plane = 0; plane < num_planes; ++plane) {
789
161k
    if (plane && !xd->is_chroma_ref) break;
790
130k
    const int mi_x = mi_col * MI_SIZE;
791
130k
    const int mi_y = mi_row * MI_SIZE;
792
130k
    dec_build_inter_predictors(cm, dcb, plane, xd->mi[0],
793
130k
                               xd->plane[plane].width, xd->plane[plane].height,
794
130k
                               mi_x, mi_y, 0);
795
796
130k
    int is_intra_inter_allowed = 1;
797
130k
    if (mbmi->tree_type == SHARED_PART &&
798
124k
        mbmi->region_type == MIXED_INTER_INTRA_REGION &&
799
0
        mbmi->chroma_ref_info.offset_started && plane > 0) {
800
0
      is_intra_inter_allowed = 0;
801
0
    }
802
803
130k
    if (is_interintra_pred(xd->mi[0]) && is_intra_inter_allowed) {
804
0
      BUFFER_SET ctx = { { xd->plane[0].dst.buf, xd->plane[1].dst.buf,
805
0
                           xd->plane[2].dst.buf },
806
0
                         { xd->plane[0].dst.stride, xd->plane[1].dst.stride,
807
0
                           xd->plane[2].dst.stride } };
808
0
      av2_build_interintra_predictor(cm, xd, xd->plane[plane].dst.buf,
809
0
                                     xd->plane[plane].dst.stride, &ctx, plane,
810
0
                                     bsize);
811
0
    }
812
130k
  }
813
814
64.0k
  if (mbmi->morph_pred) {
815
35.5k
    assert(av2_allow_intrabc(cm, xd, bsize));
816
35.5k
    assert(av2_allow_intrabc_morph_pred(cm));
817
35.5k
    assert(is_intrabc_block(mbmi, xd->tree_type));
818
35.5k
    av2_build_morph_pred(cm, xd, bsize, mi_row, mi_col);
819
35.5k
  }
820
64.0k
}
821
822
static AVM_INLINE void predict_inter_block(AV2_COMMON *const cm,
823
                                           DecoderCodingBlock *dcb,
824
64.0k
                                           BLOCK_SIZE bsize) {
825
64.0k
  MACROBLOCKD *const xd = &dcb->xd;
826
64.0k
  MB_MODE_INFO *mbmi = xd->mi[0];
827
64.0k
  const int num_planes = av2_num_planes(cm);
828
64.0k
  const int mi_row = xd->mi_row;
829
64.0k
  const int mi_col = xd->mi_col;
830
64.0k
  const int is_compound =
831
64.0k
      has_second_ref(mbmi) || is_tip_ref_frame(mbmi->ref_frame[0]);
832
128k
  for (int ref = 0; ref < 1 + is_compound; ++ref) {
833
64.0k
    const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
834
64.0k
    if (frame == INTRA_FRAME) {
835
64.0k
      assert(is_intrabc_block(mbmi, xd->tree_type));
836
64.0k
      assert(ref == 0);
837
64.0k
    } else {
838
0
      const RefCntBuffer *ref_buf = is_tip_ref_frame(mbmi->ref_frame[0])
839
0
                                        ? cm->tip_ref.ref_frame_buffer[ref]
840
0
                                        : get_ref_frame_buf(cm, frame);
841
0
      const struct scale_factors *ref_scale_factors =
842
0
          get_ref_scale_factors_const(cm, frame);
843
844
0
      xd->block_ref_scale_factors[ref] = ref_scale_factors;
845
0
      av2_setup_pre_planes(xd, ref, &ref_buf->buf, mi_row, mi_col,
846
0
                           ref_scale_factors, num_planes,
847
0
                           &mbmi->chroma_ref_info);
848
0
    }
849
64.0k
  }
850
851
64.0k
  dec_build_inter_predictor(cm, dcb, mi_row, mi_col, bsize);
852
853
#if CONFIG_MISMATCH_DEBUG
854
  const int plane_start = get_partition_plane_start(xd->tree_type);
855
  const int plane_end = get_partition_plane_end(xd->tree_type, num_planes);
856
  for (int plane = plane_start; plane < plane_end; ++plane) {
857
    const struct macroblockd_plane *pd = &xd->plane[plane];
858
    int pixel_c, pixel_r;
859
    if (plane && !xd->is_chroma_ref) continue;
860
    if (plane) {
861
      mi_to_pixel_loc(&pixel_c, &pixel_r,
862
                      mbmi->chroma_ref_info.mi_col_chroma_base,
863
                      mbmi->chroma_ref_info.mi_row_chroma_base, 0, 0,
864
                      pd->subsampling_x, pd->subsampling_y);
865
    } else {
866
      mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, 0, 0,
867
                      pd->subsampling_x, pd->subsampling_y);
868
    }
869
    int pixels_c = (cm->mi_params.mi_cols * MI_SIZE) >> pd->subsampling_x;
870
    int pixels_r = (cm->mi_params.mi_rows * MI_SIZE) >> pd->subsampling_y;
871
    mismatch_check_block_pre(
872
        pd->dst.buf, pd->dst.stride, cm->current_frame.display_order_hint,
873
        pixels_c, pixels_r, plane, pixel_c, pixel_r, pd->width, pd->height);
874
  }
875
#endif  // CONFIG_MISMATCH_DEBUG
876
877
#if CONFIG_INSPECTION
878
  for (int plane = 0; plane < num_planes; plane++) {
879
    struct macroblockd_plane *const pd = &xd->plane[plane];
880
    const int dst_stride = pd->dst.stride;
881
    const int plane_block_size =
882
        get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
883
    const int plane_width = mi_size_wide[plane_block_size];
884
    const int plane_height = mi_size_high[plane_block_size];
885
    for (int i = 0; i < plane_height * MI_SIZE; i++) {
886
      for (int j = 0; j < plane_width * MI_SIZE; j++) {
887
        uint16_t pixel = pd->dst.buf[i * dst_stride + j];
888
        int stride = cm->predicted_pixels.strides[plane > 0];
889
        int pixel_c, pixel_r;
890
        if (plane) {
891
          mi_to_pixel_loc(&pixel_c, &pixel_r,
892
                          mbmi->chroma_ref_info.mi_col_chroma_base,
893
                          mbmi->chroma_ref_info.mi_row_chroma_base, 0, 0,
894
                          pd->subsampling_x, pd->subsampling_y);
895
        } else {
896
          mi_to_pixel_loc(&pixel_c, &pixel_r, xd->mi_col, xd->mi_row, 0, 0,
897
                          pd->subsampling_x, pd->subsampling_y);
898
        }
899
        pixel_c += j;
900
        pixel_r += i;
901
        cm->predicted_pixels.buffers[plane][pixel_r * stride + pixel_c] = pixel;
902
      }
903
    }
904
  }
905
#endif  // CONFIG_INSPECTION
906
64.0k
}
907
908
static AVM_INLINE void copy_frame_mvs_inter_block(AV2_COMMON *const cm,
909
                                                  DecoderCodingBlock *dcb,
910
1.13M
                                                  BLOCK_SIZE bsize) {
911
1.13M
  if (!frame_is_intra_only(cm) &&
912
0
      cm->seq_params.order_hint_info.enable_ref_frame_mvs) {
913
0
    MACROBLOCKD *const xd = &dcb->xd;
914
0
    MB_MODE_INFO *const mi = xd->mi[0];
915
0
    const int bw = mi_size_wide[bsize];
916
0
    const int bh = mi_size_high[bsize];
917
0
    const int x_inside_boundary =
918
0
        AVMMIN(bw, cm->mi_params.mi_cols - xd->mi_col);
919
0
    const int y_inside_boundary =
920
0
        AVMMIN(bh, cm->mi_params.mi_rows - xd->mi_row);
921
0
    if (enable_refined_mvs_in_tmvp(cm, xd, mi)) {
922
0
      av2_copy_frame_refined_mvs(cm, xd, mi, xd->mi_row, xd->mi_col,
923
0
                                 x_inside_boundary, y_inside_boundary);
924
0
    } else {
925
0
      av2_copy_frame_mvs(cm, xd, mi, xd->mi_row, xd->mi_col, x_inside_boundary,
926
0
                         y_inside_boundary);
927
0
    }
928
0
  }
929
1.13M
}
930
931
static AVM_INLINE void set_color_index_map_offset(MACROBLOCKD *const xd,
932
22.4k
                                                  int plane, avm_reader *r) {
933
22.4k
  (void)r;
934
22.4k
  Av2ColorMapParam params;
935
22.4k
  const MB_MODE_INFO *const mbmi = xd->mi[0];
936
22.4k
  av2_get_block_dimensions(mbmi->sb_type[plane > 0], plane, xd,
937
22.4k
                           &params.plane_width, &params.plane_height, NULL,
938
22.4k
                           NULL);
939
22.4k
  xd->color_index_map_offset[plane] += params.plane_width * params.plane_height;
940
22.4k
}
941
942
0
void dec_bru_swap_stage(AV2_COMMON *cm, MACROBLOCKD *const xd) {
943
0
  if (cm->bru.enabled) {
944
0
    RefCntBuffer *tmp_buf = cm->cur_frame;
945
0
    if (bru_swap_common(cm)) {
946
0
      BufferPool *pool = cm->buffer_pool;
947
0
      lock_buffer_pool(pool);
948
0
      if (tmp_buf != NULL) {
949
0
        assert(tmp_buf->ref_count == 0);
950
0
        if (tmp_buf->ref_count == 0 && tmp_buf->raw_frame_buffer.data) {
951
0
          pool->release_fb_cb(pool->cb_priv, &tmp_buf->raw_frame_buffer);
952
0
          tmp_buf->raw_frame_buffer.data = NULL;
953
0
          tmp_buf->raw_frame_buffer.size = 0;
954
0
          tmp_buf->raw_frame_buffer.priv = NULL;
955
0
        }
956
0
      }
957
0
      unlock_buffer_pool(pool);
958
0
      xd->cur_buf = &cm->cur_frame->buf;
959
0
    } else {
960
0
      avm_internal_error(&cm->error, AVM_CODEC_ERROR,
961
0
                         "Decoder BRU swap stage error");
962
0
    }
963
    // correctly extend borders after swap
964
    // todo: this can be simplified by only extend support SB border
965
    // avm_extend_frame_borders(&cm->cur_frame->buf, num_planes);
966
    // Note, do not touch any recon region except the border
967
    // first col of sb
968
0
    const int sb_cols =
969
0
        (cm->mi_params.mi_cols + cm->mib_size - 1) / cm->mib_size;
970
0
    const int sb_rows =
971
0
        (cm->mi_params.mi_rows + cm->mib_size - 1) / cm->mib_size;
972
0
    for (int sb_row = 0; sb_row < sb_rows; sb_row++) {
973
0
      const int sb_mi_row = sb_row << cm->mib_size_log2;
974
0
      const int sb_mi_col = 0;
975
0
      BruActiveMode active_mode =
976
0
          av2_get_sb_info(cm, sb_mi_row, sb_mi_col)->sb_active_mode;
977
0
      if (active_mode == BRU_SUPPORT_SB) {
978
0
        bru_extend_mc_border(cm, sb_mi_row, sb_mi_col, cm->sb_size,
979
0
                             &cm->cur_frame->buf);
980
0
      }
981
0
    }
982
    // first row of sb
983
0
    for (int sb_col = 0; sb_col < sb_cols; sb_col++) {
984
0
      const int sb_mi_row = 0;
985
0
      const int sb_mi_col = sb_col << cm->mib_size_log2;
986
0
      BruActiveMode active_mode =
987
0
          av2_get_sb_info(cm, sb_mi_row, sb_mi_col)->sb_active_mode;
988
0
      if (active_mode == BRU_SUPPORT_SB) {
989
0
        bru_extend_mc_border(cm, sb_mi_row, sb_mi_col, cm->sb_size,
990
0
                             &cm->cur_frame->buf);
991
0
      }
992
0
    }
993
    // last col of sb
994
0
    for (int sb_row = 0; sb_row < sb_rows; sb_row++) {
995
0
      const int sb_mi_row = sb_row << cm->mib_size_log2;
996
0
      const int sb_mi_col = (sb_cols - 1) << cm->mib_size_log2;
997
0
      BruActiveMode active_mode =
998
0
          av2_get_sb_info(cm, sb_mi_row, sb_mi_col)->sb_active_mode;
999
0
      if (active_mode == BRU_SUPPORT_SB) {
1000
0
        bru_extend_mc_border(cm, sb_mi_row, sb_mi_col, cm->sb_size,
1001
0
                             &cm->cur_frame->buf);
1002
0
      }
1003
0
    }
1004
    // last row of sb
1005
0
    for (int sb_col = 0; sb_col < sb_cols; sb_col++) {
1006
0
      const int sb_mi_row = (sb_rows - 1) << cm->mib_size_log2;
1007
0
      const int sb_mi_col = sb_col << cm->mib_size_log2;
1008
0
      BruActiveMode active_mode =
1009
0
          av2_get_sb_info(cm, sb_mi_row, sb_mi_col)->sb_active_mode;
1010
0
      if (active_mode == BRU_SUPPORT_SB) {
1011
0
        bru_extend_mc_border(cm, sb_mi_row, sb_mi_col, cm->sb_size,
1012
0
                             &cm->cur_frame->buf);
1013
0
      }
1014
0
    }
1015
0
  }
1016
0
}
1017
1018
static AVM_INLINE int bridge_frame_is_valid_inter(const AV2_COMMON *const cm,
1019
64.0k
                                                  MACROBLOCKD *const xd) {
1020
64.0k
  if (!cm->bridge_frame_info.is_bridge_frame) return 1;
1021
0
  const MB_MODE_INFO *const mbmi = xd->mi[0];
1022
0
  const int tip_ref_frame = is_tip_ref_frame(mbmi->ref_frame[0]);
1023
0
  const int is_compound = has_second_ref(mbmi);
1024
0
  if (tip_ref_frame || is_compound) return 0;
1025
0
  if (mbmi->ref_frame[0] != cm->bridge_frame_info.bridge_frame_ref_idx_remapped)
1026
0
    return 0;
1027
0
  const int_mv mi_mv = mbmi->mv[0];
1028
  // MV must be (0,0)
1029
0
  if (mi_mv.as_int != 0) {
1030
0
    return 0;
1031
0
  }
1032
0
  return 1;
1033
0
}
1034
1035
static AVM_INLINE void decode_token_recon_block(AV2Decoder *const pbi,
1036
                                                ThreadData *const td,
1037
                                                avm_reader *r,
1038
                                                PARTITION_TYPE partition,
1039
1.13M
                                                BLOCK_SIZE bsize) {
1040
1.13M
  AV2_COMMON *const cm = &pbi->common;
1041
1.13M
  DecoderCodingBlock *const dcb = &td->dcb;
1042
1.13M
  MACROBLOCKD *const xd = &dcb->xd;
1043
1.13M
  MB_MODE_INFO *mbmi = xd->mi[0];
1044
1.13M
  xd->mi[0]->partition = partition;
1045
1.13M
  const int plane_start = get_partition_plane_start(xd->tree_type);
1046
1.13M
  const int plane_end =
1047
1.13M
      get_partition_plane_end(xd->tree_type, av2_num_planes(cm));
1048
1.13M
  const int mu128_wide = mi_size_wide[BLOCK_128X128];
1049
1.13M
  const int mu128_high = mi_size_high[BLOCK_128X128];
1050
1051
1.13M
  if (!is_inter_block(mbmi, xd->tree_type)) {
1052
    // When row_mt is used, this function can be called with
1053
    // td->read_coeffs_tx_intra_block_visit == decode_block_void.
1054
    // In that case do not reset since it will erase previously set
1055
    // values.
1056
    // intra cannot be used in non-active SBs
1057
1.06M
    if (!bru_is_sb_active(cm, xd->mi_col, xd->mi_row)) {
1058
0
      avm_internal_error(
1059
0
          &cm->error, AVM_CODEC_ERROR,
1060
0
          "Invalid BRU activte: only active SB can be predicted by intra");
1061
0
    }
1062
1.06M
    if (cm->bridge_frame_info.is_bridge_frame) {
1063
0
      avm_internal_error(
1064
0
          &cm->error, AVM_CODEC_ERROR,
1065
0
          "Invalid Bridge frame activate: can not be predicted by intra");
1066
0
    }
1067
1.06M
    if (td->read_coeffs_tx_intra_block_visit != decode_block_void)
1068
1.07M
      av2_init_txk_skip_array(cm, xd->mi_row, xd->mi_col, bsize, 0,
1069
1.07M
                              xd->tree_type, &mbmi->chroma_ref_info,
1070
1.07M
                              plane_start, plane_end);
1071
1.06M
    int row, col;
1072
1073
1.06M
    xd->cfl.use_dc_pred_cache = 0;
1074
1.06M
    xd->cfl.dc_pred_is_cached[0] = 0;
1075
1.06M
    xd->cfl.dc_pred_is_cached[1] = 0;
1076
1.06M
    assert(bsize == get_plane_block_size(bsize, xd->plane[0].subsampling_x,
1077
1.06M
                                         xd->plane[0].subsampling_y));
1078
1.06M
    const int max_blocks_wide = max_block_wide(xd, bsize, 0);
1079
1.06M
    const int max_blocks_high = max_block_high(xd, bsize, 0);
1080
1.06M
    const BLOCK_SIZE max_unit_bsize = BLOCK_64X64;
1081
1.06M
    int mu_blocks_wide = mi_size_wide[max_unit_bsize];
1082
1.06M
    int mu_blocks_high = mi_size_high[max_unit_bsize];
1083
1.06M
    mu_blocks_wide = AVMMIN(max_blocks_wide, mu_blocks_wide);
1084
1.06M
    mu_blocks_high = AVMMIN(max_blocks_high, mu_blocks_high);
1085
1086
    // For 256x256 and 256x128 coding blocks, the coefficents/resdiuals are
1087
    // divided into 64x* blocks, and each 64x64 block is coded in 128x128 unit.
1088
    // For example, for a 256x256 coding block, the coding order of 64x64
1089
    // residual blocks are following:
1090
    // A B E F
1091
    // C D G H
1092
    // I J M N
1093
    // K L O P
1094
1095
    // Loop through each 128x128 block within the current coding block
1096
2.14M
    for (int row128 = 0; row128 < max_blocks_high; row128 += mu128_high) {
1097
2.14M
      for (int col128 = 0; col128 < max_blocks_wide; col128 += mu128_wide) {
1098
        // Loop through each 64x64 block within the current 128x128 block
1099
2.17M
        for (row = row128; row < AVMMIN(row128 + mu128_high, max_blocks_high);
1100
1.10M
             row += mu_blocks_high) {
1101
2.25M
          for (col = col128; col < AVMMIN(col128 + mu128_wide, max_blocks_wide);
1102
1.15M
               col += mu_blocks_wide) {
1103
3.69M
            for (int plane = plane_start; plane < plane_end; ++plane) {
1104
2.57M
              if (plane == AVM_PLANE_Y && !xd->lossless[mbmi->segment_id]) {
1105
953k
                const struct macroblockd_plane *const pd = &xd->plane[plane];
1106
953k
                const int ss_x = pd->subsampling_x;
1107
953k
                const int ss_y = pd->subsampling_y;
1108
953k
                const BLOCK_SIZE plane_bsize =
1109
953k
                    get_mb_plane_block_size(xd, mbmi, plane, ss_x, ss_y);
1110
953k
                const int plane_unit_height =
1111
953k
                    get_plane_tx_unit_height(xd, plane_bsize, plane, row, ss_y);
1112
953k
                const int plane_unit_width =
1113
953k
                    get_plane_tx_unit_width(xd, plane_bsize, plane, col, ss_x);
1114
1115
953k
                const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
1116
953k
                get_tx_partition_sizes(mbmi->tx_partition_type[0], max_tx_size,
1117
953k
                                       &mbmi->txb_pos, mbmi->sub_txs,
1118
953k
                                       xd->error_info);
1119
1120
2.09M
                for (int txb_idx = 0; txb_idx < mbmi->txb_pos.n_partitions;
1121
1.14M
                     ++txb_idx) {
1122
1.14M
                  const TX_SIZE tx_size = mbmi->sub_txs[txb_idx];
1123
1.14M
                  mbmi->txb_idx = txb_idx;
1124
1.14M
                  int blk_row = row + mbmi->txb_pos.row_offset[txb_idx];
1125
1.14M
                  int blk_col = col + mbmi->txb_pos.col_offset[txb_idx];
1126
1127
1.14M
                  if (blk_row >= plane_unit_height ||
1128
1.14M
                      blk_col >= plane_unit_width)
1129
481
                    continue;
1130
1131
1.14M
                  td->read_coeffs_tx_intra_block_visit(
1132
1.14M
                      cm, dcb, r, plane, blk_row, blk_col, tx_size);
1133
1.14M
                  td->predict_and_recon_intra_block_visit(
1134
1.14M
                      cm, dcb, r, plane, blk_row, blk_col, tx_size);
1135
1.14M
                  set_cb_buffer_offsets(dcb, tx_size, plane);
1136
1.14M
                }
1137
                // finish luma coding
1138
1.61M
              } else {
1139
1.61M
                if (plane && !xd->is_chroma_ref) break;
1140
1.58M
                const struct macroblockd_plane *const pd = &xd->plane[plane];
1141
1.58M
                const int ss_x = pd->subsampling_x;
1142
1.58M
                const int ss_y = pd->subsampling_y;
1143
1.58M
                const BLOCK_SIZE plane_bsize =
1144
1.58M
                    get_mb_plane_block_size(xd, mbmi, plane, ss_x, ss_y);
1145
1.58M
                const TX_SIZE tx_size = av2_get_tx_size(plane, xd);
1146
1.58M
                if (plane == AVM_PLANE_U && is_cctx_allowed(cm, xd)) continue;
1147
947k
                const int stepr = tx_size_high_unit[tx_size];
1148
947k
                const int stepc = tx_size_wide_unit[tx_size];
1149
947k
                const int plane_unit_height =
1150
947k
                    get_plane_tx_unit_height(xd, plane_bsize, plane, row, ss_y);
1151
947k
                const int plane_unit_width =
1152
947k
                    get_plane_tx_unit_width(xd, plane_bsize, plane, col, ss_x);
1153
1154
947k
                const bool lossless = xd->lossless[mbmi->segment_id];
1155
947k
                const bool need_parsing =
1156
947k
                    !skip_parsing_recon(row, col, ss_x, ss_y, lossless);
1157
947k
                const bool need_reconstrution =
1158
947k
                    mbmi->uv_mode != UV_CFL_PRED || lossless
1159
947k
                        ? need_parsing
1160
947k
                        : !((row + mu_blocks_high < max_blocks_high) ||
1161
364k
                            (col + mu_blocks_wide < max_blocks_wide));
1162
1163
2.12M
                for (int blk_row = row >> ss_y; blk_row < plane_unit_height;
1164
1.18M
                     blk_row += stepr) {
1165
4.01M
                  for (int blk_col = col >> ss_x; blk_col < plane_unit_width;
1166
2.83M
                       blk_col += stepc) {
1167
2.83M
                    if (plane == AVM_PLANE_V && is_cctx_allowed(cm, xd)) {
1168
634k
                      if (need_parsing) {
1169
589k
                        td->read_coeffs_tx_intra_block_visit(
1170
589k
                            cm, dcb, r, AVM_PLANE_U, blk_row, blk_col, tx_size);
1171
589k
                        td->read_coeffs_tx_intra_block_visit(
1172
589k
                            cm, dcb, r, AVM_PLANE_V, blk_row, blk_col, tx_size);
1173
589k
                        td->inverse_cctx_block_visit(cm, dcb, r, -1, blk_row,
1174
589k
                                                     blk_col, tx_size);
1175
589k
                      }
1176
1177
634k
                      if (need_reconstrution) {
1178
589k
                        td->predict_and_recon_intra_block_visit(
1179
589k
                            cm, dcb, r, AVM_PLANE_U, blk_row & 0xf0,
1180
589k
                            blk_col & 0xf0, tx_size);
1181
589k
                        td->predict_and_recon_intra_block_visit(
1182
589k
                            cm, dcb, r, AVM_PLANE_V, blk_row & 0xf0,
1183
589k
                            blk_col & 0xf0, tx_size);
1184
589k
                      }
1185
634k
                      if (need_reconstrution) {
1186
590k
                        set_cb_buffer_offsets(dcb, tx_size, AVM_PLANE_U);
1187
590k
                        set_cb_buffer_offsets(dcb, tx_size, AVM_PLANE_V);
1188
590k
                      }
1189
2.19M
                    } else {
1190
2.19M
                      assert(plane == AVM_PLANE_Y || !is_cctx_allowed(cm, xd));
1191
2.19M
                      if (need_parsing)
1192
2.14M
                        td->read_coeffs_tx_intra_block_visit(
1193
2.14M
                            cm, dcb, r, plane, blk_row, blk_col, tx_size);
1194
2.19M
                      if (need_reconstrution) {
1195
2.11M
                        td->predict_and_recon_intra_block_visit(
1196
2.11M
                            cm, dcb, r, plane,
1197
2.11M
                            blk_row & (lossless ? 0xff : 0xf0),
1198
2.11M
                            blk_col & (lossless ? 0xff : 0xf0), tx_size);
1199
2.11M
                      }
1200
2.19M
                      if (need_reconstrution)
1201
2.13M
                        set_cb_buffer_offsets(dcb, tx_size, plane);
1202
2.19M
                    }
1203
2.83M
                  }
1204
1.18M
                }
1205
                // finish coding of the chroma components
1206
947k
              }
1207
2.57M
            }
1208
1.15M
          }
1209
1.10M
        }
1210
1.07M
      }
1211
1.07M
    }
1212
1.06M
  } else {
1213
    // When row_mt is used, this function can be called with
1214
    // td->read_coeffs_tx_inter_block_visit == decode_block_void.
1215
    // In that case do not reset since it will erase previously set
1216
    // values.
1217
    // check BRU inter prediction motion vector
1218
65.6k
    if (!bru_is_valid_inter(cm, xd)) {
1219
0
      avm_internal_error(&cm->error, AVM_CODEC_ERROR,
1220
0
                         "Invalid BRU inter prediction");
1221
0
    }
1222
65.6k
    if (!bridge_frame_is_valid_inter(cm, xd)) {
1223
0
      avm_internal_error(&cm->error, AVM_CODEC_ERROR,
1224
0
                         "Invalid Bridge frame inter prediction");
1225
0
    }
1226
65.6k
    if (td->read_coeffs_tx_inter_block_visit != decode_block_void)
1227
64.0k
      av2_init_txk_skip_array(cm, xd->mi_row, xd->mi_col, bsize, 0,
1228
64.0k
                              xd->tree_type, &mbmi->chroma_ref_info,
1229
64.0k
                              plane_start, plane_end);
1230
65.6k
    td->predict_inter_block_visit(cm, dcb, bsize);
1231
    // Reconstruction
1232
65.6k
    if (!mbmi->skip_txfm[xd->tree_type == CHROMA_PART]) {
1233
17.7k
      int eobtotal = 0;
1234
17.7k
      if (!bru_is_sb_active(cm, xd->mi_col, xd->mi_row)) {
1235
0
        avm_internal_error(
1236
0
            &cm->error, AVM_CODEC_ERROR,
1237
0
            "Invalid BRU skip_txfm: only active SB has transform");
1238
0
      }
1239
17.7k
      if (cm->bridge_frame_info.is_bridge_frame) {
1240
0
        avm_internal_error(
1241
0
            &cm->error, AVM_CODEC_ERROR,
1242
0
            "Invalid Bridge frame skip_txfm: can not have transform");
1243
0
      }
1244
17.7k
      const int max_blocks_wide = max_block_wide(xd, bsize, 0);
1245
17.7k
      const int max_blocks_high = max_block_high(xd, bsize, 0);
1246
17.7k
      int row, col;
1247
1248
17.7k
      const BLOCK_SIZE max_unit_bsize = BLOCK_64X64;
1249
17.7k
      assert(max_unit_bsize ==
1250
17.7k
             get_plane_block_size(BLOCK_64X64, xd->plane[0].subsampling_x,
1251
17.7k
                                  xd->plane[0].subsampling_y));
1252
17.7k
      int mu_blocks_wide = mi_size_wide[max_unit_bsize];
1253
17.7k
      int mu_blocks_high = mi_size_high[max_unit_bsize];
1254
1255
17.7k
      mu_blocks_wide = AVMMIN(max_blocks_wide, mu_blocks_wide);
1256
17.7k
      mu_blocks_high = AVMMIN(max_blocks_high, mu_blocks_high);
1257
1258
      // Loop through each 128x128 block within the current coding block
1259
35.4k
      for (int row128 = 0; row128 < max_blocks_high; row128 += mu128_high) {
1260
35.4k
        for (int col128 = 0; col128 < max_blocks_wide; col128 += mu128_wide) {
1261
          // Loop through each 64x64 block within the current 128x128 block
1262
35.4k
          for (row = row128; row < AVMMIN(row128 + mu128_high, max_blocks_high);
1263
17.7k
               row += mu_blocks_high) {
1264
17.7k
            for (col = col128;
1265
35.4k
                 col < AVMMIN(col128 + mu128_wide, max_blocks_wide);
1266
17.7k
                 col += mu_blocks_wide) {
1267
60.1k
              for (int plane = plane_start; plane < plane_end; ++plane) {
1268
44.4k
                if (plane && !xd->is_chroma_ref) break;
1269
42.4k
                const struct macroblockd_plane *const pd = &xd->plane[plane];
1270
42.4k
                const int ss_x = pd->subsampling_x;
1271
42.4k
                const int ss_y = pd->subsampling_y;
1272
42.4k
                const BLOCK_SIZE plane_bsize =
1273
42.4k
                    get_mb_plane_block_size(xd, mbmi, plane, ss_x, ss_y);
1274
42.4k
                const TX_SIZE max_tx_size =
1275
42.4k
                    get_vartx_max_txsize(xd, plane_bsize, plane);
1276
42.4k
                const int bh_var_tx = tx_size_high_unit[max_tx_size];
1277
42.4k
                const int bw_var_tx = tx_size_wide_unit[max_tx_size];
1278
42.4k
                const int plane_unit_height =
1279
42.4k
                    get_plane_tx_unit_height(xd, plane_bsize, plane, row, ss_y);
1280
42.4k
                const int plane_unit_width =
1281
42.4k
                    get_plane_tx_unit_width(xd, plane_bsize, plane, col, ss_x);
1282
1283
                // When chroma TU is assocated with multiple luma TUs, the
1284
                // chroma TU is parsed/reconstructed fewer times than
1285
                // associated luama TUs. For example, in YUV420 format, one
1286
                // 64x64 chroma TU is associated with four 64x64 luma TUs,
1287
                // the parsing and reconstruction of the first 64x64 chroma
1288
                // TU is done once for the first 64x64 luma TU and skipped
1289
                // for the remaining three 64x64 TUs.
1290
42.4k
                const bool lossless = xd->lossless[mbmi->segment_id];
1291
42.4k
                if (skip_parsing_recon(row, col, ss_x, ss_y, lossless)) {
1292
0
                  continue;
1293
0
                }
1294
86.0k
                for (int blk_row = row >> ss_y; blk_row < plane_unit_height;
1295
43.6k
                     blk_row += bh_var_tx) {
1296
93.2k
                  for (int blk_col = col >> ss_x; blk_col < plane_unit_width;
1297
49.6k
                       blk_col += bw_var_tx) {
1298
49.6k
                    decode_reconstruct_tx(cm, td, r, mbmi, plane, plane_bsize,
1299
49.6k
                                          blk_row, blk_col, max_tx_size,
1300
49.6k
                                          &eobtotal);
1301
49.6k
                  }
1302
43.6k
                }
1303
42.4k
              }
1304
17.7k
            }
1305
17.7k
          }
1306
17.7k
        }
1307
17.7k
      }
1308
47.8k
    } else if (is_cctx_enabled(cm, xd) && xd->is_chroma_ref &&
1309
17.8k
               xd->tree_type != LUMA_PART) {
1310
17.8k
      av2_init_txk_skip_array(cm, xd->mi_row, xd->mi_col, bsize, 1,
1311
17.8k
                              xd->tree_type, &mbmi->chroma_ref_info,
1312
17.8k
                              plane_start, plane_end);
1313
      // fill cctx_type_map with CCTX_NONE for skip blocks so their
1314
      // neighbors can derive cctx contexts
1315
17.8k
      const struct macroblockd_plane *const pd = &xd->plane[AVM_PLANE_U];
1316
17.8k
      const int ss_x = pd->subsampling_x;
1317
17.8k
      const int ss_y = pd->subsampling_y;
1318
17.8k
      const BLOCK_SIZE uv_plane_bsize =
1319
17.8k
          get_mb_plane_block_size(xd, mbmi, AVM_PLANE_U, ss_x, ss_y);
1320
17.8k
      const TX_SIZE max_tx_size =
1321
17.8k
          get_vartx_max_txsize(xd, uv_plane_bsize, AVM_PLANE_U);
1322
17.8k
      const int max_blocks_wide = max_block_wide(xd, bsize, 0);
1323
17.8k
      const int max_blocks_high = max_block_high(xd, bsize, 0);
1324
17.8k
      const BLOCK_SIZE max_unit_bsize = BLOCK_64X64;
1325
17.8k
      int mu_blocks_wide = mi_size_wide[max_unit_bsize];
1326
17.8k
      int mu_blocks_high = mi_size_high[max_unit_bsize];
1327
      // Loop through each 128x128 block within the current coding block
1328
35.6k
      for (int row128 = 0; row128 < max_blocks_high; row128 += mu128_high) {
1329
35.6k
        for (int col128 = 0; col128 < max_blocks_wide; col128 += mu128_wide) {
1330
          // Loop through each 64x64 block within the current 128x128 block
1331
17.8k
          for (int row = row128;
1332
35.6k
               row < AVMMIN(row128 + mu128_high, max_blocks_high);
1333
17.8k
               row += mu_blocks_high) {
1334
17.8k
            for (int col = col128;
1335
35.6k
                 col < AVMMIN(col128 + mu128_wide, max_blocks_wide);
1336
17.8k
                 col += mu_blocks_wide) {
1337
17.8k
              int row_offset, col_offset;
1338
17.8k
              get_chroma_mi_offsets(xd, &row_offset, &col_offset);
1339
17.8k
              update_cctx_array(xd, 0, 0, row_offset, col_offset, max_tx_size,
1340
17.8k
                                CCTX_NONE);
1341
17.8k
            }
1342
17.8k
          }
1343
17.8k
        }
1344
17.8k
      }
1345
30.0k
    } else {
1346
30.0k
      av2_init_txk_skip_array(cm, xd->mi_row, xd->mi_col, bsize, 1,
1347
30.0k
                              xd->tree_type, &mbmi->chroma_ref_info,
1348
30.0k
                              plane_start, plane_end);
1349
30.0k
    }
1350
65.6k
  }
1351
1352
1.13M
  td->copy_frame_mvs_block_visit(cm, dcb, bsize);
1353
1354
1.13M
  av2_visit_palette(pbi, xd, r, set_color_index_map_offset);
1355
1.13M
  av2_mark_block_as_coded(xd, bsize, cm->sb_size);
1356
1.13M
}
1357
1358
static TX_SIZE read_tx_partition(MACROBLOCKD *xd, MB_MODE_INFO *mbmi,
1359
                                 TX_SIZE max_tx_size, int blk_row, int blk_col,
1360
182k
                                 avm_reader *r) {
1361
182k
  int plane_type = (xd->tree_type == CHROMA_PART);
1362
182k
  const BLOCK_SIZE bsize = mbmi->sb_type[plane_type];
1363
182k
  const int is_inter = is_inter_block(mbmi, xd->tree_type);
1364
182k
  const int max_blocks_high = max_block_high(xd, bsize, 0);
1365
182k
  const int max_blocks_wide = max_block_wide(xd, bsize, 0);
1366
182k
  if (is_inter && (blk_row >= max_blocks_high || blk_col >= max_blocks_wide))
1367
0
    return TX_INVALID;
1368
182k
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
1369
182k
  const int allow_horz = allow_tx_horz_split(bsize, max_tx_size);
1370
182k
  const int allow_vert = allow_tx_vert_split(bsize, max_tx_size);
1371
182k
  TX_PARTITION_TYPE partition = 0;
1372
182k
  const int is_fsc = (xd->mi[0]->fsc_mode[xd->tree_type == CHROMA_PART] &&
1373
527
                      plane_type == PLANE_TYPE_Y);
1374
182k
  const int bsize_group = size_to_tx_part_group_lookup[bsize];
1375
182k
  const int txsize_group_h_and_v = get_vert_and_horz_group(bsize);
1376
182k
  const int txsize_group_h_or_v = get_vert_or_horz_group(bsize);
1377
182k
  assert(!(txsize_group_h_and_v == BLOCK_INVALID &&
1378
182k
           txsize_group_h_or_v == BLOCK_INVALID));
1379
182k
  int do_partition = 0;
1380
182k
  if (allow_horz || allow_vert) {
1381
171k
    avm_cdf_prob *do_partition_cdf =
1382
171k
        ec_ctx->txfm_do_partition_cdf[is_fsc][is_inter][bsize_group];
1383
171k
    do_partition =
1384
171k
        avm_read_symbol(r, do_partition_cdf, 2, ACCT_INFO("do_partition"));
1385
171k
  }
1386
1387
182k
  if (do_partition) {
1388
83.6k
    if (allow_horz && allow_vert) {
1389
      // Read 4way tree type
1390
80.2k
      assert(txsize_group_h_or_v > 0);
1391
80.2k
      avm_cdf_prob *partition_type_cdf =
1392
80.2k
          ec_ctx->txfm_4way_partition_type_cdf[is_fsc][is_inter]
1393
80.2k
                                              [txsize_group_h_and_v];
1394
1395
80.2k
      const TX_PARTITION_TYPE partition_type =
1396
80.2k
          avm_read_symbol(r, partition_type_cdf, TX_PARTITION_TYPE_NUM,
1397
80.2k
                          ACCT_INFO("partition_type"));
1398
80.2k
      partition = partition_type + 1;
1399
80.2k
    } else if (txsize_group_h_or_v) {
1400
2.14k
      avm_cdf_prob *partition_type_cdf =
1401
2.14k
          ec_ctx->txfm_2or3_way_partition_type_cdf[is_fsc][is_inter]
1402
2.14k
                                                  [txsize_group_h_or_v - 1];
1403
2.14k
      const TX_PARTITION_TYPE partition_type =
1404
2.14k
          xd->reduced_tx_part_set
1405
2.14k
              ? 0
1406
2.14k
              : avm_read_symbol(r, partition_type_cdf, 2,
1407
2.14k
                                ACCT_INFO("partition_type"));
1408
2.14k
      if (allow_horz) {
1409
1.31k
        switch (partition_type) {
1410
1.17k
          case 0: partition = TX_PARTITION_HORZ; break;
1411
134
          case 1: partition = TX_PARTITION_HORZ4; break;
1412
0
          default: assert(0); break;
1413
1.31k
        }
1414
1.31k
      } else {
1415
833
        switch (partition_type) {
1416
766
          case 0: partition = TX_PARTITION_VERT; break;
1417
68
          case 1: partition = TX_PARTITION_VERT4; break;
1418
0
          default: assert(0); break;
1419
833
        }
1420
833
      }
1421
2.14k
    } else {
1422
1.27k
      partition = allow_horz ? TX_PARTITION_HORZ : TX_PARTITION_VERT;
1423
1.27k
    }
1424
98.7k
  } else {
1425
98.7k
    partition = TX_PARTITION_NONE;
1426
98.7k
  }
1427
1428
182k
  TX_SIZE sub_txs[MAX_TX_PARTITIONS] = { 0 };
1429
182k
  int num_txfm_blocks = get_tx_partition_sizes(
1430
182k
      partition, max_tx_size, &mbmi->txb_pos, sub_txs, xd->error_info);
1431
182k
  mbmi->tx_size = sub_txs[num_txfm_blocks - 1];
1432
182k
  int index = is_inter ? av2_get_txb_size_index(bsize, blk_row, blk_col) : 0;
1433
182k
  mbmi->tx_partition_type[index] = partition;
1434
182k
  return sub_txs[num_txfm_blocks - 1];
1435
182k
}
1436
1437
static TX_SIZE read_tx_size(MACROBLOCKD *xd, TX_MODE tx_mode, int is_inter,
1438
962k
                            int allow_select_inter, avm_reader *r) {
1439
962k
  const BLOCK_SIZE bsize = xd->mi[0]->sb_type[xd->tree_type == CHROMA_PART];
1440
962k
  if (xd->lossless[xd->mi[0]->segment_id]) {
1441
27.9k
    const bool is_fsc = xd->mi[0]->fsc_mode[xd->tree_type == CHROMA_PART];
1442
27.9k
    if (bsize == BLOCK_4X4 || (!is_inter && !is_fsc) || !allow_select_inter)
1443
26.8k
      return TX_4X4;
1444
1.02k
    else {
1445
1.02k
      const int bsize_group = size_group_lookup[bsize];
1446
1.02k
      const int is_tx_size_large = avm_read_symbol(
1447
1.02k
          r, xd->tile_ctx->lossless_tx_size_cdf[bsize_group][is_inter], 2,
1448
1.02k
          ACCT_INFO("lossless_tx_size"));
1449
1.02k
      if (is_tx_size_large) {
1450
523
        return lossless_max_txsize_lookup[bsize];
1451
523
      }
1452
504
      return (TX_SIZE)is_tx_size_large;
1453
1.02k
    }
1454
27.9k
  }
1455
1456
935k
  if (block_signals_txsize(bsize)) {
1457
882k
    if ((!is_inter || allow_select_inter) && tx_mode == TX_MODE_SELECT) {
1458
181k
      MB_MODE_INFO *mbmi = xd->mi[0];
1459
181k
      const TX_SIZE max_tx_size = max_txsize_rect_lookup[bsize];
1460
181k
      return read_tx_partition(xd, mbmi, max_tx_size, 0, 0, r);
1461
701k
    } else {
1462
701k
      return tx_size_from_tx_mode(bsize, tx_mode);
1463
701k
    }
1464
882k
  } else {
1465
52.3k
    assert(IMPLIES(tx_mode == ONLY_4X4, bsize == BLOCK_4X4));
1466
52.3k
    return max_txsize_rect_lookup[bsize];
1467
52.3k
  }
1468
935k
}
1469
static BruActiveMode read_bru_mode(AV2_COMMON *cm, const MACROBLOCKD *xd,
1470
0
                                   avm_reader *r) {
1471
0
  if (!cm->bru.enabled) return 0;
1472
0
  BruActiveMode sb_active_mode = BRU_ACTIVE_SB;
1473
0
  if (is_sb_start_mi(cm, xd->mi_col, xd->mi_row)) {
1474
0
    if (xd->tile.tile_active_mode == 0) {
1475
0
      sb_active_mode = BRU_INACTIVE_SB;
1476
0
    } else {
1477
0
      FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
1478
      // 0 inactive, 1 support, 2 active
1479
0
      sb_active_mode = (BruActiveMode)avm_read_symbol(
1480
0
          r, ec_ctx->bru_mode_cdf, 3, ACCT_INFO("sb_active_mode"));
1481
0
    }
1482
0
    xd->sbi->sb_active_mode = sb_active_mode;
1483
0
  } else {
1484
0
    const SB_INFO *sbi = av2_get_sb_info(cm, xd->mi_row, xd->mi_col);
1485
0
    sb_active_mode = sbi->sb_active_mode;
1486
0
  }
1487
0
  return sb_active_mode;
1488
0
}
1489
static AVM_INLINE void parse_decode_block(AV2Decoder *const pbi,
1490
                                          ThreadData *const td, int mi_row,
1491
                                          int mi_col, avm_reader *r,
1492
                                          PARTITION_TYPE partition,
1493
                                          BLOCK_SIZE bsize,
1494
1.14M
                                          PARTITION_TREE *parent, int index) {
1495
1.14M
  DecoderCodingBlock *const dcb = &td->dcb;
1496
1.14M
  MACROBLOCKD *const xd = &dcb->xd;
1497
1.14M
  const int max_aspect_ratio =
1498
1.14M
      1 << (pbi->common.seq_params.max_pb_aspect_ratio_log2_m1 + 1);
1499
1.14M
  const int blk_w = block_size_wide[bsize];
1500
1.14M
  const int blk_h = block_size_high[bsize];
1501
1.14M
  if (blk_w > blk_h * max_aspect_ratio || blk_h > blk_w * max_aspect_ratio) {
1502
0
    avm_internal_error(
1503
0
        xd->error_info, AVM_CODEC_CORRUPT_FRAME,
1504
0
        "Block size %dx%d violates aspect ratio constraint of %d", blk_w, blk_h,
1505
0
        max_aspect_ratio);
1506
0
  }
1507
1.14M
  decode_mbmi_block(pbi, dcb, mi_row, mi_col, r, partition, bsize, parent,
1508
1.14M
                    index);
1509
1510
1.14M
  av2_visit_palette(pbi, xd, r, av2_decode_palette_tokens);
1511
1512
1.14M
  AV2_COMMON *cm = &pbi->common;
1513
1.14M
  const int num_planes = av2_num_planes(cm);
1514
1.14M
  MB_MODE_INFO *mbmi = xd->mi[0];
1515
1.14M
  int inter_block_tx = is_inter_block(mbmi, xd->tree_type) ||
1516
1.07M
                       is_intrabc_block(mbmi, xd->tree_type);
1517
1.14M
  xd->reduced_tx_part_set = cm->seq_params.reduced_tx_part_set;
1518
1.14M
  if (xd->tree_type != CHROMA_PART) {
1519
963k
    memset(mbmi->tx_partition_type, TX_PARTITION_NONE,
1520
963k
           sizeof(mbmi->tx_partition_type));
1521
963k
    if (cm->features.tx_mode == TX_MODE_SELECT && block_signals_txsize(bsize) &&
1522
184k
        !mbmi->skip_txfm[xd->tree_type == CHROMA_PART] && inter_block_tx &&
1523
1.37k
        !xd->lossless[mbmi->segment_id]) {
1524
1.29k
      const TX_SIZE max_tx_size = max_txsize_rect_lookup[bsize];
1525
1.29k
      const int bh = tx_size_high_unit[max_tx_size];
1526
1.29k
      const int bw = tx_size_wide_unit[max_tx_size];
1527
1.29k
      const int width = mi_size_wide[bsize];
1528
1.29k
      const int height = mi_size_high[bsize];
1529
1530
2.58k
      for (int idy = 0; idy < height; idy += bh)
1531
2.58k
        for (int idx = 0; idx < width; idx += bw)
1532
1.29k
          read_tx_partition(xd, mbmi, max_tx_size, idy, idx, r);
1533
962k
    } else {
1534
962k
      mbmi->tx_size =
1535
962k
          read_tx_size(xd, cm->features.tx_mode, inter_block_tx,
1536
962k
                       !mbmi->skip_txfm[xd->tree_type == CHROMA_PART], r);
1537
962k
    }
1538
963k
  }
1539
1540
1.14M
  if (cm->delta_q_info.delta_q_present_flag) {
1541
6.63M
    for (int i = 0; i < MAX_SEGMENTS; i++) {
1542
6.21M
      const int current_qindex = av2_get_qindex(
1543
6.21M
          &cm->seg, i, xd->current_base_qindex, cm->seq_params.bit_depth);
1544
1545
6.21M
      const CommonQuantParams *const quant_params = &cm->quant_params;
1546
22.4M
      for (int j = 0; j < num_planes; ++j) {
1547
16.1M
        const int dc_delta_q = j == 0 ? quant_params->y_dc_delta_q
1548
16.1M
                                      : (j == 1 ? quant_params->u_dc_delta_q
1549
10.6M
                                                : quant_params->v_dc_delta_q);
1550
16.1M
        const int ac_delta_q = j == 0 ? 0
1551
16.1M
                                      : (j == 1 ? quant_params->u_ac_delta_q
1552
10.3M
                                                : quant_params->v_ac_delta_q);
1553
16.1M
        xd->plane[j].seg_dequant_QTX[i][0] =
1554
16.1M
            av2_dc_quant_QTX(current_qindex, dc_delta_q,
1555
16.1M
                             j == 0 ? cm->seq_params.base_y_dc_delta_q
1556
16.1M
                                    : cm->seq_params.base_uv_dc_delta_q,
1557
16.1M
                             cm->seq_params.bit_depth);
1558
16.1M
        xd->plane[j].seg_dequant_QTX[i][1] =
1559
16.1M
            av2_ac_quant_QTX(current_qindex, ac_delta_q,
1560
16.1M
                             j == 0 ? 0 : cm->seq_params.base_uv_ac_delta_q,
1561
16.1M
                             cm->seq_params.bit_depth);
1562
16.1M
      }
1563
6.21M
    }
1564
418k
  }
1565
1.14M
  assert(bsize == mbmi->sb_type[av2_get_sdp_idx(xd->tree_type)]);
1566
1.14M
  if (mbmi->skip_txfm[xd->tree_type == CHROMA_PART])
1567
46.3k
    av2_reset_entropy_context(xd, bsize, num_planes);
1568
  // For regular decoder, always do recon
1569
  // For optimized decoder, only do reocn when support SB
1570
1.14M
  if (!pbi->bru_opt_mode ||
1571
0
      (pbi->bru_opt_mode && bru_is_sb_active(cm, mi_col, mi_row)))
1572
1.13M
    decode_token_recon_block(pbi, td, r, partition, bsize);
1573
1574
  // Note: the copying here must match corresponding encoder-side copying in
1575
  // av2_update_state().
1576
  // TODO(any): Refactor.
1577
1.14M
  if (xd->tree_type != SHARED_PART) {
1578
506k
    const int bh = mi_size_high[bsize];
1579
506k
    const int bw = mi_size_wide[bsize];
1580
506k
    const CommonModeInfoParams *const mi_params = &cm->mi_params;
1581
506k
    const int x_inside_boundary = AVMMIN(bw, mi_params->mi_cols - mi_col);
1582
506k
    const int y_inside_boundary = AVMMIN(bh, mi_params->mi_rows - mi_row);
1583
506k
    int idx = mi_params->mi_stride;
1584
506k
    assert(x_inside_boundary && y_inside_boundary);
1585
506k
    if (xd->tree_type != CHROMA_PART) {
1586
2.28M
      for (int y = 0; y < y_inside_boundary; ++y) {
1587
16.2M
        for (int x = 0; x < x_inside_boundary; ++x) {
1588
14.3M
          if (x == 0 && y == 0) continue;
1589
13.9M
          set_blk_offsets(mi_params, xd, mi_row, mi_col, y, x);
1590
13.9M
          *(xd->mi[y * idx + x]) = *(xd->mi[0]);
1591
13.9M
        }
1592
1.94M
      }
1593
332k
    } else {
1594
173k
      assert(x_inside_boundary && y_inside_boundary);
1595
1.58M
      for (int y = 0; y < y_inside_boundary; ++y) {
1596
14.2M
        for (int x = 0; x < x_inside_boundary; ++x) {
1597
12.8M
          if (x == 0 && y == 0) continue;
1598
12.6M
          set_blk_offsets(mi_params, xd, mi_row, mi_col, y, x);
1599
12.6M
          xd->mi[y * idx + x]->sb_type[PLANE_TYPE_UV] =
1600
12.6M
              xd->mi[0]->sb_type[PLANE_TYPE_UV];
1601
12.6M
          xd->mi[y * idx + x]->uv_mode = xd->mi[0]->uv_mode;
1602
12.6M
          xd->mi[y * idx + x]->angle_delta[PLANE_TYPE_UV] =
1603
12.6M
              xd->mi[0]->angle_delta[PLANE_TYPE_UV];
1604
12.6M
          xd->mi[y * idx + x]->cfl_alpha_signs = xd->mi[0]->cfl_alpha_signs;
1605
12.6M
          xd->mi[y * idx + x]->cfl_alpha_idx = xd->mi[0]->cfl_alpha_idx;
1606
12.6M
          xd->mi[y * idx + x]->partition = xd->mi[0]->partition;
1607
12.6M
          xd->mi[y * idx + x]->chroma_mi_row_start =
1608
12.6M
              xd->mi[0]->chroma_mi_row_start;
1609
12.6M
          xd->mi[y * idx + x]->chroma_mi_col_start =
1610
12.6M
              xd->mi[0]->chroma_mi_col_start;
1611
12.6M
          if (av2_allow_palette(PLANE_TYPE_UV,
1612
12.6M
                                cm->features.allow_screen_content_tools,
1613
12.6M
                                bsize)) {
1614
0
            xd->mi[y * idx + x]->palette_mode_info.palette_size[PLANE_TYPE_UV] =
1615
0
                xd->mi[0]->palette_mode_info.palette_size[PLANE_TYPE_UV];
1616
0
            for (int i = PALETTE_MAX_SIZE; i < 3 * PALETTE_MAX_SIZE; i++)
1617
0
              xd->mi[y * idx + x]->palette_mode_info.palette_colors[i] =
1618
0
                  xd->mi[0]->palette_mode_info.palette_colors[i];
1619
0
          }
1620
12.6M
        }
1621
1.41M
      }
1622
173k
    }
1623
506k
  }
1624
1.14M
}
1625
1626
static AVM_INLINE void set_offsets_for_pred_and_recon(AV2Decoder *const pbi,
1627
                                                      ThreadData *const td,
1628
                                                      int mi_row, int mi_col,
1629
0
                                                      BLOCK_SIZE bsize) {
1630
0
  AV2_COMMON *const cm = &pbi->common;
1631
0
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
1632
0
  DecoderCodingBlock *const dcb = &td->dcb;
1633
0
  MACROBLOCKD *const xd = &dcb->xd;
1634
0
  const int bw = mi_size_wide[bsize];
1635
0
  const int bh = mi_size_high[bsize];
1636
0
  const int num_planes = av2_num_planes(cm);
1637
1638
0
  const int offset = mi_row * mi_params->mi_stride + mi_col;
1639
0
  const TileInfo *const tile = &xd->tile;
1640
1641
0
  xd->mi = mi_params->mi_grid_base + offset;
1642
0
  xd->tx_type_map =
1643
0
      &mi_params->tx_type_map[mi_row * mi_params->mi_stride + mi_col];
1644
0
  xd->tx_type_map_stride = mi_params->mi_stride;
1645
0
  xd->cctx_type_map =
1646
0
      &mi_params->cctx_type_map[mi_row * mi_params->mi_stride + mi_col];
1647
0
  xd->cctx_type_map_stride = mi_params->mi_stride;
1648
1649
  // It is assumed that CHROMA_REF_INFO is already set (during parsing stage).
1650
0
  CHROMA_REF_INFO chroma_ref_info = xd->mi[0]->chroma_ref_info;
1651
  // In case of semi-decoupled partitions, the variable is_chroma_ref is set to
1652
  // 0 while parsing luma tree and is set to 1 while parsing chroma tree. Thus,
1653
  // the value of is_chroma_ref set during parsing stage cannot be used and
1654
  // needs to be explicitly updated here based on tree type.
1655
0
  if (xd->tree_type != SHARED_PART)
1656
0
    chroma_ref_info.is_chroma_ref = xd->tree_type == LUMA_PART ? 0 : 1;
1657
0
  set_plane_n4(xd, bw, bh, num_planes, &chroma_ref_info);
1658
1659
  // Distance of Mb to the various image edges. These are specified to 8th pel
1660
  // as they are always compared to values that are in 1/8th pel units
1661
0
  set_mi_row_col(cm, xd, tile, mi_row, bh, mi_col, bw, mi_params->mi_rows,
1662
0
                 mi_params->mi_cols, &chroma_ref_info);
1663
1664
0
  av2_setup_dst_planes(xd->plane, &cm->cur_frame->buf, mi_row, mi_col, 0,
1665
0
                       num_planes, &chroma_ref_info);
1666
0
}
1667
1668
static AVM_INLINE void decode_block(AV2Decoder *const pbi, ThreadData *const td,
1669
                                    int mi_row, int mi_col, avm_reader *r,
1670
                                    PARTITION_TYPE partition, BLOCK_SIZE bsize,
1671
0
                                    PARTITION_TREE *parent, int index) {
1672
0
  (void)partition;
1673
0
  (void)parent;
1674
0
  (void)index;
1675
0
  const int max_aspect_ratio =
1676
0
      1 << (pbi->common.seq_params.max_pb_aspect_ratio_log2_m1 + 1);
1677
0
  const int blk_w = block_size_wide[bsize];
1678
0
  const int blk_h = block_size_high[bsize];
1679
0
  if (blk_w > blk_h * max_aspect_ratio || blk_h > blk_w * max_aspect_ratio) {
1680
0
    avm_internal_error(
1681
0
        td->dcb.xd.error_info, AVM_CODEC_CORRUPT_FRAME,
1682
0
        "Block size %dx%d violates aspect ratio constraint of %d", blk_w, blk_h,
1683
0
        max_aspect_ratio);
1684
0
  }
1685
0
  set_offsets_for_pred_and_recon(pbi, td, mi_row, mi_col, bsize);
1686
0
  decode_token_recon_block(pbi, td, r, partition, bsize);
1687
0
}
1688
1689
/*!\brief Maps (ext_part, 4way, 4way_type, rect_type) to partition_type. */
1690
static PARTITION_TYPE
1691
    rect_part_table[2][2][NUM_UNEVEN_4WAY_PARTS][NUM_RECT_PARTS] = {
1692
      {
1693
          // !do_ext_partition
1694
          {
1695
              // !do_4way
1696
              { // UNEVEN_4A
1697
                PARTITION_HORZ, PARTITION_VERT },
1698
              { // UNEVEN_4B
1699
                PARTITION_HORZ, PARTITION_VERT },
1700
          },
1701
          {
1702
              // do_4way
1703
              { // UNEVEN_4A
1704
                PARTITION_HORZ, PARTITION_VERT },
1705
              { // UNEVEN_4B
1706
                PARTITION_HORZ, PARTITION_VERT },
1707
          },
1708
      },
1709
      {
1710
          // do_ext_partition
1711
          {
1712
              // !do_4way
1713
              { // UNEVEN_4A
1714
                PARTITION_HORZ_3, PARTITION_VERT_3 },
1715
              { // UNEVEN_4B
1716
                PARTITION_HORZ_3, PARTITION_VERT_3 },
1717
          },
1718
          {
1719
              // do_4way
1720
              { // UNEVEN_4A
1721
                PARTITION_HORZ_4A, PARTITION_VERT_4A },
1722
              { // UNEVEN_4B
1723
                PARTITION_HORZ_4B, PARTITION_VERT_4B },
1724
          },
1725
      },
1726
    };
1727
1728
static PARTITION_TYPE read_partition(const AV2_COMMON *const cm,
1729
                                     MACROBLOCKD *xd, int mi_row, int mi_col,
1730
                                     avm_reader *r, int has_rows, int has_cols,
1731
                                     const PARTITION_TREE *ptree,
1732
                                     const PARTITION_TREE *ptree_luma,
1733
1.93M
                                     BLOCK_SIZE bsize) {
1734
1.93M
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
1735
1736
1.93M
  (void)has_rows;
1737
1.93M
  (void)has_cols;
1738
1.93M
  const int plane = xd->tree_type == CHROMA_PART;
1739
1.93M
  const int ssx = cm->seq_params.subsampling_x;
1740
1.93M
  const int ssy = cm->seq_params.subsampling_y;
1741
1.93M
  PARTITION_TYPE derived_partition = av2_get_normative_forced_partition_type(
1742
1.93M
      &cm->mi_params, xd->tree_type, ssx, ssy, mi_row, mi_col, bsize,
1743
1.93M
      ptree_luma);
1744
1745
1.93M
  bool partition_allowed[ALL_PARTITION_TYPES];
1746
1.93M
  init_allowed_partitions_for_signaling(
1747
1.93M
      partition_allowed, cm, xd->tree_type,
1748
1.93M
      (ptree->parent ? ptree->parent->region_type : INTRA_REGION), mi_row,
1749
1.93M
      mi_col, ssx, ssy, bsize, &ptree->chroma_ref_info);
1750
1.93M
  if (derived_partition != PARTITION_INVALID &&
1751
109k
      partition_allowed[derived_partition]) {
1752
109k
    return derived_partition;
1753
109k
  }
1754
1755
1.82M
  derived_partition = only_allowed_partition(partition_allowed);
1756
1.82M
  if (derived_partition != PARTITION_INVALID) {
1757
31.4k
    return derived_partition;
1758
31.4k
  }
1759
1760
1.82M
  bool do_split;
1761
1.79M
  bool implied_do_split;
1762
  // allow do whatever implied first, then if not possible
1763
  // use BRU to set do split to false
1764
1.79M
  if (is_do_split_implied(partition_allowed, &implied_do_split)) {
1765
    // BRU inactive won't go futher implied partition
1766
25.5k
    if (!bru_is_sb_active(cm, mi_col, mi_row) ||
1767
25.5k
        cm->bridge_frame_info.is_bridge_frame) {
1768
0
      do_split = false;
1769
0
    } else
1770
25.5k
      do_split = implied_do_split;
1771
1.77M
  } else {
1772
    // if not derived partition, based on inactive/support set do_split to false
1773
1.77M
    if (!bru_is_sb_active(cm, mi_col, mi_row) ||
1774
1.76M
        cm->bridge_frame_info.is_bridge_frame) {
1775
0
      do_split = false;
1776
1.77M
    } else {
1777
1.77M
      const int ctx =
1778
1.77M
          partition_plane_context(xd, mi_row, mi_col, bsize, 0, SPLIT_CTX_MODE);
1779
1.77M
      do_split = avm_read_symbol(r, ec_ctx->do_split_cdf[plane][ctx], 2,
1780
1.77M
                                 ACCT_INFO("do_split"));
1781
1.77M
    }
1782
1.77M
  }
1783
1.79M
  if (!do_split) {
1784
1.00M
    return PARTITION_NONE;
1785
1.00M
  }
1786
1787
796k
  if (partition_allowed[PARTITION_SPLIT]) {
1788
32.4k
    const int square_split_ctx = partition_plane_context(
1789
32.4k
        xd, mi_row, mi_col, bsize, 0, SQUARE_SPLIT_CTX_MODE);
1790
32.4k
    const bool do_square_split =
1791
32.4k
        avm_read_symbol(r, ec_ctx->do_square_split_cdf[plane][square_split_ctx],
1792
32.4k
                        2, ACCT_INFO("do_square_split"));
1793
32.4k
    if (do_square_split) {
1794
24.0k
      return PARTITION_SPLIT;
1795
24.0k
    }
1796
32.4k
  }
1797
1798
772k
  RECT_PART_TYPE rect_type = rect_type_implied_by_bsize(bsize, xd->tree_type);
1799
772k
  if (rect_type == RECT_INVALID) {
1800
718k
    rect_type = only_allowed_rect_type(partition_allowed);
1801
718k
  }
1802
772k
  if (rect_type == RECT_INVALID) {
1803
706k
    const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize, 0,
1804
706k
                                            RECT_TYPE_CTX_MODE);
1805
706k
    rect_type = avm_read_symbol(r, ec_ctx->rect_type_cdf[plane][ctx],
1806
706k
                                NUM_RECT_PARTS, ACCT_INFO("rect_type"));
1807
706k
  }
1808
1809
772k
  bool do_ext_partition = false;
1810
772k
  bool do_uneven_4way_partition = false;
1811
772k
  UNEVEN_4WAY_PART_TYPE uneven_4way_partition_type = UNEVEN_4A;
1812
772k
  bool implied_do_ext;
1813
772k
  if (is_do_ext_partition_implied(partition_allowed, rect_type,
1814
772k
                                  &implied_do_ext)) {
1815
492k
    do_ext_partition = implied_do_ext;
1816
492k
  } else {
1817
280k
    const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize,
1818
280k
                                            rect_type, EXT_PART_CTX_MODE);
1819
280k
    do_ext_partition =
1820
280k
        avm_read_symbol(r, ec_ctx->do_ext_partition_cdf[plane][0][ctx], 2,
1821
280k
                        ACCT_INFO("do_ext_partition"));
1822
280k
  }
1823
772k
  if (do_ext_partition) {
1824
34.9k
    bool implied_do_uneven_4way;
1825
34.9k
    if (is_do_uneven_4way_partition_implied(partition_allowed, rect_type,
1826
34.9k
                                            &implied_do_uneven_4way)) {
1827
22.4k
      do_uneven_4way_partition = implied_do_uneven_4way;
1828
22.4k
    } else {
1829
12.4k
      const int ctx = partition_plane_context(xd, mi_row, mi_col, bsize,
1830
12.4k
                                              rect_type, FOUR_WAY_CTX_MODE);
1831
12.4k
      do_uneven_4way_partition = avm_read_symbol(
1832
12.4k
          r, ec_ctx->do_uneven_4way_partition_cdf[plane][0][ctx], 2,
1833
12.4k
          ACCT_INFO("do_uneven_4way_partition"));
1834
12.4k
    }
1835
34.9k
    if (do_uneven_4way_partition) {
1836
4.31k
      uneven_4way_partition_type =
1837
4.31k
          avm_read_bit(r, ACCT_INFO("uneven_4way_partition_type"));
1838
4.31k
    }
1839
34.9k
  }
1840
772k
  return rect_part_table[do_ext_partition][do_uneven_4way_partition]
1841
772k
                        [uneven_4way_partition_type][rect_type];
1842
796k
}
1843
1844
// Set the superblock level parameters
1845
160k
static void set_sb_mv_precision(SB_INFO *sbi, AV2Decoder *const pbi) {
1846
160k
  AV2_COMMON *const cm = &pbi->common;
1847
160k
  sbi->sb_mv_precision = cm->features.fr_mv_precision;
1848
160k
}
1849
1850
// TODO(slavarnway): eliminate bsize and subsize in future commits
1851
static AVM_INLINE void decode_partition(
1852
    AV2Decoder *const pbi, ThreadData *const td, int mi_row, int mi_col,
1853
    avm_reader *reader, BLOCK_SIZE bsize, SB_INFO *sbi, PARTITION_TREE *ptree,
1854
2.17M
    PARTITION_TREE *ptree_luma, int parse_decode_flag) {
1855
2.17M
  assert(bsize < BLOCK_SIZES_ALL);
1856
2.17M
  AV2_COMMON *const cm = &pbi->common;
1857
2.17M
  DecoderCodingBlock *const dcb = &td->dcb;
1858
2.17M
  MACROBLOCKD *const xd = &dcb->xd;
1859
2.17M
  const int ss_x = xd->plane[1].subsampling_x;
1860
2.17M
  const int ss_y = xd->plane[1].subsampling_y;
1861
  // Half block width/height.
1862
2.17M
  const int hbs_w = mi_size_wide[bsize] / 2;
1863
2.17M
  const int hbs_h = mi_size_high[bsize] / 2;
1864
  // One-eighth block width/height.
1865
2.17M
  const int ebs_w = mi_size_wide[bsize] / 8;
1866
2.17M
  const int ebs_h = mi_size_high[bsize] / 8;
1867
2.17M
  PARTITION_TYPE partition;
1868
2.17M
  const int has_rows = (mi_row + hbs_h) < cm->mi_params.mi_rows;
1869
2.17M
  const int has_cols = (mi_col + hbs_w) < cm->mi_params.mi_cols;
1870
1871
2.17M
  if (mi_row >= cm->mi_params.mi_rows || mi_col >= cm->mi_params.mi_cols) {
1872
63.0k
    av2_mark_block_as_pseudo_coded(xd, mi_row, mi_col, bsize, cm->sb_size);
1873
63.0k
    return;
1874
63.0k
  }
1875
1876
2.11M
  const int is_intra_sdp_enabled = is_sdp_enabled_in_keyframe(cm);
1877
2.11M
  const int total_loop_num =
1878
2.11M
      is_intra_sdp_enabled && bsize == BLOCK_64X64 ? 2 : 1;
1879
2.11M
  if (total_loop_num == 2 && xd->tree_type == SHARED_PART) {
1880
68.0k
    xd->tree_type = LUMA_PART;
1881
68.0k
    decode_partition(pbi, td, mi_row, mi_col, reader, bsize, sbi, ptree,
1882
68.0k
                     ptree_luma, parse_decode_flag);
1883
68.0k
    xd->tree_type = CHROMA_PART;
1884
1885
68.0k
    decode_partition(pbi, td, mi_row, mi_col, reader, bsize, sbi, ptree_luma,
1886
68.0k
                     ptree, parse_decode_flag);
1887
68.0k
    xd->tree_type = SHARED_PART;
1888
68.0k
    return;
1889
68.0k
  }
1890
1891
  // parse_decode_flag takes the following values :
1892
  // 01 - do parse only
1893
  // 10 - do decode only
1894
  // 11 - do parse and decode
1895
2.04M
  static const block_visitor_fn_t block_visit[4] = { NULL, parse_decode_block,
1896
2.04M
                                                     decode_block,
1897
2.04M
                                                     parse_decode_block };
1898
2.04M
  if (ptree->parent) {
1899
1.87M
    if (ptree->parent->bsize == cm->sb_size) {
1900
227k
      if (ptree->parent->partition == PARTITION_VERT)
1901
43.3k
        ptree->sb_root_partition_info = SB_VERT_PARTITION;
1902
184k
      else if (ptree->parent->partition == PARTITION_HORZ ||
1903
138k
               ptree->parent->partition == PARTITION_SPLIT)
1904
139k
        ptree->sb_root_partition_info = SB_HORZ_OR_QUAD_PARTITION;
1905
45.2k
      else
1906
45.2k
        ptree->sb_root_partition_info = INVALID_INTRABC_SB_PARTITION;
1907
1.65M
    } else {
1908
1.65M
      ptree->sb_root_partition_info = ptree->parent->sb_root_partition_info;
1909
1.65M
    }
1910
1.87M
  }
1911
1912
2.04M
  const int is_sb_root = bsize == cm->sb_size;
1913
2.04M
  if (is_sb_root) {
1914
161k
    xd->is_cfl_allowed_in_sdp =
1915
161k
        is_cfl_allowed_for_sdp(cm, xd, ptree_luma, PARTITION_NONE, bsize);
1916
161k
    ptree->is_cfl_allowed_for_this_chroma_partition = CFL_DISALLOWED_FOR_CHROMA;
1917
161k
    if (!frame_is_intra_only(cm)) {
1918
0
      ptree->region_type = MIXED_INTER_INTRA_REGION;
1919
0
      ptree->extended_sdp_allowed_flag = cm->seq_params.enable_extended_sdp;
1920
161k
    } else {
1921
161k
      ptree->region_type = INTRA_REGION;
1922
161k
      ptree->extended_sdp_allowed_flag = 0;
1923
161k
    }
1924
161k
  }
1925
1926
2.04M
  if (parse_decode_flag & 1) {
1927
2.03M
    if (is_sb_root) {
1928
160k
      if (cm->bru.enabled || cm->bridge_frame_info.is_bridge_frame) {
1929
0
        const int mi_grid_idx = get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
1930
0
        const int mi_alloc_idx =
1931
0
            get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
1932
0
        cm->mi_params.mi_grid_base[mi_grid_idx] =
1933
0
            &cm->mi_params.mi_alloc[mi_alloc_idx];
1934
        // 'xd->mi' should point to an offset in 'mi_grid_base';
1935
0
        xd->mi = cm->mi_params.mi_grid_base + mi_grid_idx;
1936
0
        xd->mi[0]->sb_type[xd->tree_type == CHROMA_PART] = bsize;
1937
0
        xd->mi_row = mi_row;
1938
0
        xd->mi_col = mi_col;
1939
0
        if (!cm->bridge_frame_info.is_bridge_frame) {
1940
0
          xd->sbi->sb_active_mode = read_bru_mode(cm, xd, reader);
1941
0
          set_active_map(cm, mi_col, mi_row, xd->sbi->sb_active_mode);
1942
0
        }
1943
0
      }
1944
160k
      set_sb_mv_precision(sbi, pbi);
1945
160k
    }
1946
2.03M
    const int plane_start = get_partition_plane_start(xd->tree_type);
1947
2.03M
    const int plane_end =
1948
2.03M
        get_partition_plane_end(xd->tree_type, av2_num_planes(cm));
1949
6.66M
    for (int plane = plane_start; plane < plane_end; ++plane) {
1950
4.62M
      int rcol0, rcol1, rrow0, rrow1;
1951
4.62M
      if ((cm->rst_info[plane].frame_restoration_type != RESTORE_NONE) &&
1952
246k
          av2_loop_restoration_corners_in_sb(cm, plane, mi_row, mi_col, bsize,
1953
246k
                                             &rcol0, &rcol1, &rrow0, &rrow1)) {
1954
12.9k
        const int rstride = cm->rst_info[plane].horz_units_per_frame;
1955
25.8k
        for (int rrow = rrow0; rrow < rrow1; ++rrow) {
1956
25.8k
          for (int rcol = rcol0; rcol < rcol1; ++rcol) {
1957
12.9k
            const int runit_idx = rcol + rrow * rstride;
1958
12.9k
            loop_restoration_read_sb_coeffs(cm, xd, reader, plane, runit_idx);
1959
12.9k
          }
1960
12.9k
        }
1961
12.9k
      }
1962
4.62M
    }
1963
1964
2.03M
    ptree->bsize = bsize;
1965
2.03M
    ptree->mi_row = mi_row;
1966
2.03M
    ptree->mi_col = mi_col;
1967
2.03M
    ptree->is_settled = 1;
1968
1969
2.03M
    if (is_intra_sdp_enabled && xd->tree_type == SHARED_PART) {
1970
35.3k
      ptree_luma->bsize = bsize;
1971
35.3k
      ptree_luma->mi_row = mi_row;
1972
35.3k
      ptree_luma->mi_col = mi_col;
1973
35.3k
      ptree_luma->is_settled = 1;
1974
35.3k
      ptree_luma->is_cfl_allowed_for_this_chroma_partition =
1975
35.3k
          CFL_DISALLOWED_FOR_CHROMA;
1976
35.3k
    }
1977
1978
2.03M
    PARTITION_TREE *parent = ptree->parent;
1979
2.03M
    set_chroma_ref_info(
1980
2.03M
        xd->tree_type, mi_row, mi_col, ptree->index, bsize,
1981
2.03M
        &ptree->chroma_ref_info, parent ? &parent->chroma_ref_info : NULL,
1982
2.03M
        parent ? parent->bsize : BLOCK_INVALID,
1983
2.03M
        parent ? parent->partition : PARTITION_NONE, ss_x, ss_y);
1984
1985
2.03M
    partition = !is_partition_point(bsize)
1986
2.03M
                    ? PARTITION_NONE
1987
2.03M
                    : read_partition(cm, xd, mi_row, mi_col, reader, has_rows,
1988
1.93M
                                     has_cols, ptree, ptree_luma, bsize);
1989
2.03M
    ptree->is_cfl_allowed_for_this_chroma_partition |=
1990
2.03M
        is_cfl_allowed_for_sdp(cm, xd, ptree_luma, partition, bsize);
1991
2.03M
    CFL_ALLOWED_FOR_SDP_TYPE is_cfl_allowed_in_sdp =
1992
2.03M
        ptree->is_cfl_allowed_for_this_chroma_partition;
1993
2.03M
    ptree->partition = partition;
1994
1995
2.03M
    if (!is_sb_root && parent) {
1996
1.87M
      if (parent->extended_sdp_allowed_flag)
1997
0
        ptree->extended_sdp_allowed_flag =
1998
0
            is_extended_sdp_allowed(cm->seq_params.enable_extended_sdp,
1999
0
                                    parent->bsize, parent->partition);
2000
1.87M
      else
2001
1.87M
        ptree->extended_sdp_allowed_flag = 0;
2002
1.87M
      if (!frame_is_intra_only(cm) && ptree->partition &&
2003
0
          parent->region_type != INTRA_REGION &&
2004
0
          ptree->extended_sdp_allowed_flag &&
2005
0
          bru_is_sb_active(cm, mi_col, mi_row) &&
2006
0
          !cm->bridge_frame_info.is_bridge_frame &&
2007
0
          is_bsize_allowed_for_extended_sdp(bsize, ptree->partition)) {
2008
0
        const int ctx = get_intra_region_context(bsize);
2009
0
        ptree->region_type =
2010
0
            avm_read_symbol(reader, xd->tile_ctx->region_type_cdf[ctx],
2011
0
                            REGION_TYPES, ACCT_INFO("region_type"));
2012
0
        if (ptree->region_type == INTRA_REGION) xd->tree_type = LUMA_PART;
2013
1.87M
      } else if (!frame_is_intra_only(cm)) {
2014
0
        ptree->region_type = parent->region_type;
2015
1.87M
      } else {
2016
1.87M
        ptree->region_type = INTRA_REGION;
2017
1.87M
      }
2018
1.87M
    }
2019
2020
2.03M
    switch (partition) {
2021
1.08k
      case PARTITION_HORZ_4A:
2022
2.19k
      case PARTITION_HORZ_4B:
2023
3.26k
      case PARTITION_VERT_4A:
2024
4.31k
      case PARTITION_VERT_4B:
2025
28.3k
      case PARTITION_SPLIT:
2026
28.3k
        ptree->sub_tree[0] = av2_alloc_ptree_node(ptree, 0);
2027
28.3k
        ptree->sub_tree[1] = av2_alloc_ptree_node(ptree, 1);
2028
28.3k
        ptree->sub_tree[2] = av2_alloc_ptree_node(ptree, 2);
2029
28.3k
        ptree->sub_tree[3] = av2_alloc_ptree_node(ptree, 3);
2030
28.3k
        if (is_intra_sdp_enabled && xd->tree_type == SHARED_PART) {
2031
8.79k
          ptree_luma->sub_tree[0] = av2_alloc_ptree_node(ptree_luma, 0);
2032
8.79k
          ptree_luma->sub_tree[1] = av2_alloc_ptree_node(ptree_luma, 1);
2033
8.79k
          ptree_luma->sub_tree[2] = av2_alloc_ptree_node(ptree_luma, 2);
2034
8.79k
          ptree_luma->sub_tree[3] = av2_alloc_ptree_node(ptree_luma, 3);
2035
8.79k
        }
2036
28.3k
        break;
2037
414k
      case PARTITION_HORZ:
2038
839k
      case PARTITION_VERT:
2039
839k
        ptree->sub_tree[0] = av2_alloc_ptree_node(ptree, 0);
2040
839k
        ptree->sub_tree[1] = av2_alloc_ptree_node(ptree, 1);
2041
2042
839k
        if (is_intra_sdp_enabled && xd->tree_type == SHARED_PART) {
2043
13.2k
          ptree_luma->sub_tree[0] = av2_alloc_ptree_node(ptree_luma, 0);
2044
13.2k
          ptree_luma->sub_tree[1] = av2_alloc_ptree_node(ptree_luma, 1);
2045
13.2k
        }
2046
839k
        break;
2047
15.1k
      case PARTITION_HORZ_3:
2048
30.6k
      case PARTITION_VERT_3:
2049
30.6k
        ptree->sub_tree[0] = av2_alloc_ptree_node(ptree, 0);
2050
30.6k
        ptree->sub_tree[1] = av2_alloc_ptree_node(ptree, 1);
2051
30.6k
        ptree->sub_tree[2] = av2_alloc_ptree_node(ptree, 2);
2052
30.6k
        ptree->sub_tree[3] = av2_alloc_ptree_node(ptree, 3);
2053
2054
30.6k
        if (is_intra_sdp_enabled && xd->tree_type == SHARED_PART) {
2055
0
          ptree_luma->sub_tree[0] = av2_alloc_ptree_node(ptree_luma, 0);
2056
0
          ptree_luma->sub_tree[1] = av2_alloc_ptree_node(ptree_luma, 1);
2057
0
          ptree_luma->sub_tree[2] = av2_alloc_ptree_node(ptree_luma, 2);
2058
0
          ptree_luma->sub_tree[3] = av2_alloc_ptree_node(ptree_luma, 3);
2059
0
        }
2060
30.6k
        break;
2061
1.14M
      default: break;
2062
2.03M
    }
2063
2.03M
    switch (partition) {
2064
1.14M
      case PARTITION_NONE:
2065
1.14M
        xd->is_cfl_allowed_in_sdp = is_cfl_allowed_in_sdp;
2066
1.14M
        break;
2067
1.08k
      case PARTITION_HORZ_4A:
2068
2.19k
      case PARTITION_HORZ_4B:
2069
3.26k
      case PARTITION_VERT_4A:
2070
4.31k
      case PARTITION_VERT_4B:
2071
19.4k
      case PARTITION_HORZ_3:
2072
34.9k
      case PARTITION_VERT_3:
2073
58.9k
      case PARTITION_SPLIT:
2074
58.9k
        ptree->sub_tree[0]->is_cfl_allowed_for_this_chroma_partition =
2075
58.9k
            is_cfl_allowed_in_sdp;
2076
58.9k
        ptree->sub_tree[1]->is_cfl_allowed_for_this_chroma_partition =
2077
58.9k
            is_cfl_allowed_in_sdp;
2078
58.9k
        ptree->sub_tree[2]->is_cfl_allowed_for_this_chroma_partition =
2079
58.9k
            is_cfl_allowed_in_sdp;
2080
58.9k
        ptree->sub_tree[3]->is_cfl_allowed_for_this_chroma_partition =
2081
58.9k
            is_cfl_allowed_in_sdp;
2082
58.9k
        break;
2083
414k
      case PARTITION_HORZ:
2084
839k
      case PARTITION_VERT:
2085
839k
        ptree->sub_tree[0]->is_cfl_allowed_for_this_chroma_partition =
2086
839k
            is_cfl_allowed_in_sdp;
2087
839k
        ptree->sub_tree[1]->is_cfl_allowed_for_this_chroma_partition =
2088
839k
            is_cfl_allowed_in_sdp;
2089
839k
        break;
2090
0
      default: break;
2091
2.03M
    }
2092
2.03M
  } else {
2093
4.28k
    partition = ptree->partition;
2094
4.28k
    const PARTITION_TREE *parent = ptree->parent;
2095
4.28k
    if (!is_sb_root && parent) {
2096
0
      if (!frame_is_intra_only(cm) && !cm->seq_params.monochrome &&
2097
0
          ptree->partition && parent->region_type != INTRA_REGION &&
2098
0
          ptree->region_type == INTRA_REGION) {
2099
0
        xd->tree_type = LUMA_PART;
2100
0
      }
2101
0
    }
2102
4.28k
  }
2103
2104
2.04M
  const BLOCK_SIZE subsize = get_partition_subsize(bsize, partition);
2105
2.04M
  if (subsize == BLOCK_INVALID) {
2106
0
    avm_internal_error(xd->error_info, AVM_CODEC_CORRUPT_FRAME,
2107
0
                       "Partition %d is invalid for block size %dx%d",
2108
0
                       partition, block_size_wide[bsize],
2109
0
                       block_size_high[bsize]);
2110
0
    assert(0);
2111
0
  }
2112
  // Check the bitstream is conformant: if there is subsampling on the
2113
  // chroma planes, subsize must subsample to a valid block size.
2114
2.04M
  const struct macroblockd_plane *const pd_u = &xd->plane[1];
2115
2.04M
  BLOCK_SIZE test_subsize = subsize;
2116
2.04M
  if (xd->tree_type == SHARED_PART) {
2117
1.18M
    const PARTITION_TREE *parent = ptree;
2118
1.18M
    CHROMA_REF_INFO chroma_ref_info;
2119
1.18M
    const int index =
2120
1.18M
        (partition == PARTITION_HORZ || partition == PARTITION_VERT) ? 1 : 0;
2121
1.18M
    set_chroma_ref_info(xd->tree_type, mi_row, mi_col, index, subsize,
2122
1.18M
                        &chroma_ref_info,
2123
1.18M
                        parent ? &parent->chroma_ref_info : NULL,
2124
18.4E
                        parent ? parent->bsize : BLOCK_INVALID,
2125
18.4E
                        parent ? parent->partition : PARTITION_NONE,
2126
1.18M
                        xd->plane[1].subsampling_x, xd->plane[1].subsampling_y);
2127
1.18M
    test_subsize = chroma_ref_info.bsize_base;
2128
1.18M
    assert(test_subsize != BLOCK_INVALID);
2129
1.18M
  }
2130
2.04M
  if (xd->tree_type != LUMA_PART &&
2131
1.45M
      get_plane_block_size(test_subsize, pd_u->subsampling_x,
2132
1.45M
                           pd_u->subsampling_y) == BLOCK_INVALID) {
2133
0
    avm_internal_error(xd->error_info, AVM_CODEC_CORRUPT_FRAME,
2134
0
                       "Block size %dx%d invalid with this subsampling mode",
2135
0
                       block_size_wide[test_subsize],
2136
0
                       block_size_high[test_subsize]);
2137
0
  }
2138
  // Check that chroma ref block isn't completely outside the boundary.
2139
2.04M
  if (!is_chroma_ref_within_boundary(
2140
2.04M
          cm, xd->tree_type, ptree->chroma_ref_info.is_chroma_ref, mi_row,
2141
2.04M
          mi_col, bsize, partition, pd_u->subsampling_x, pd_u->subsampling_y)) {
2142
0
    avm_internal_error(xd->error_info, AVM_CODEC_CORRUPT_FRAME,
2143
0
                       "Invalid partitioning %d at location [%d, %d]: chroma "
2144
0
                       "info not coded.",
2145
0
                       partition, mi_row << MI_SIZE_LOG2,
2146
0
                       mi_col << MI_SIZE_LOG2);
2147
0
  }
2148
2149
2.04M
#define DEC_BLOCK_STX_ARG
2150
2.04M
#define DEC_BLOCK_EPT_ARG partition,
2151
2.04M
#define DEC_BLOCK(db_r, db_c, db_subsize, index)                               \
2152
2.04M
  block_visit[parse_decode_flag](pbi, td, DEC_BLOCK_STX_ARG(db_r), (db_c),     \
2153
1.14M
                                 reader, DEC_BLOCK_EPT_ARG(db_subsize), ptree, \
2154
1.14M
                                 index)
2155
2.04M
#define DEC_PARTITION(db_r, db_c, db_subsize, index)                 \
2156
2.04M
  decode_partition(pbi, td, DEC_BLOCK_STX_ARG(db_r), (db_c), reader, \
2157
1.91M
                   (db_subsize), sbi, ptree->sub_tree[(index)],      \
2158
1.91M
                   get_partition_subtree_const(ptree_luma, index),   \
2159
1.91M
                   parse_decode_flag)
2160
2161
2.04M
  switch (partition) {
2162
1.14M
    case PARTITION_NONE: DEC_BLOCK(mi_row, mi_col, subsize, 0); break;
2163
414k
    case PARTITION_HORZ:
2164
414k
      DEC_PARTITION(mi_row, mi_col, subsize, 0);
2165
414k
      DEC_PARTITION(mi_row + hbs_h, mi_col, subsize, 1);
2166
414k
      break;
2167
425k
    case PARTITION_VERT:
2168
425k
      DEC_PARTITION(mi_row, mi_col, subsize, 0);
2169
425k
      DEC_PARTITION(mi_row, mi_col + hbs_w, subsize, 1);
2170
425k
      break;
2171
1.08k
    case PARTITION_HORZ_4A: {
2172
1.08k
      const BLOCK_SIZE bsize_big = get_partition_subsize(bsize, PARTITION_HORZ);
2173
1.08k
      const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_HORZ][bsize_big];
2174
1.08k
      assert(subsize == subsize_lookup[PARTITION_HORZ][bsize_med]);
2175
1.08k
      int this_mi_row = mi_row;
2176
1.08k
      DEC_PARTITION(this_mi_row, mi_col, subsize, 0);
2177
1.08k
      this_mi_row += ebs_h;
2178
1.08k
      DEC_PARTITION(this_mi_row, mi_col, bsize_med, 1);
2179
1.08k
      this_mi_row += 2 * ebs_h;
2180
1.08k
      DEC_PARTITION(this_mi_row, mi_col, bsize_big, 2);
2181
1.08k
      this_mi_row += 4 * ebs_h;
2182
1.08k
      DEC_PARTITION(this_mi_row, mi_col, subsize, 3);
2183
1.08k
      break;
2184
0
    }
2185
1.11k
    case PARTITION_HORZ_4B: {
2186
1.11k
      const BLOCK_SIZE bsize_big = get_partition_subsize(bsize, PARTITION_HORZ);
2187
1.11k
      const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_HORZ][bsize_big];
2188
1.11k
      assert(subsize == subsize_lookup[PARTITION_HORZ][bsize_med]);
2189
1.11k
      int this_mi_row = mi_row;
2190
1.11k
      DEC_PARTITION(this_mi_row, mi_col, subsize, 0);
2191
1.11k
      this_mi_row += ebs_h;
2192
1.11k
      DEC_PARTITION(this_mi_row, mi_col, bsize_big, 1);
2193
1.11k
      this_mi_row += 4 * ebs_h;
2194
1.11k
      DEC_PARTITION(this_mi_row, mi_col, bsize_med, 2);
2195
1.11k
      this_mi_row += 2 * ebs_h;
2196
1.11k
      DEC_PARTITION(this_mi_row, mi_col, subsize, 3);
2197
1.11k
      break;
2198
0
    }
2199
1.07k
    case PARTITION_VERT_4A: {
2200
1.07k
      const BLOCK_SIZE bsize_big = get_partition_subsize(bsize, PARTITION_VERT);
2201
1.07k
      const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_VERT][bsize_big];
2202
1.07k
      assert(subsize == subsize_lookup[PARTITION_VERT][bsize_med]);
2203
1.07k
      int this_mi_col = mi_col;
2204
1.07k
      DEC_PARTITION(mi_row, this_mi_col, subsize, 0);
2205
1.07k
      this_mi_col += ebs_w;
2206
1.07k
      DEC_PARTITION(mi_row, this_mi_col, bsize_med, 1);
2207
1.07k
      this_mi_col += 2 * ebs_w;
2208
1.07k
      DEC_PARTITION(mi_row, this_mi_col, bsize_big, 2);
2209
1.07k
      this_mi_col += 4 * ebs_w;
2210
1.07k
      DEC_PARTITION(mi_row, this_mi_col, subsize, 3);
2211
1.07k
      break;
2212
0
    }
2213
1.05k
    case PARTITION_VERT_4B: {
2214
1.05k
      const BLOCK_SIZE bsize_big = get_partition_subsize(bsize, PARTITION_VERT);
2215
1.05k
      const BLOCK_SIZE bsize_med = subsize_lookup[PARTITION_VERT][bsize_big];
2216
1.05k
      assert(subsize == subsize_lookup[PARTITION_VERT][bsize_med]);
2217
1.05k
      int this_mi_col = mi_col;
2218
1.05k
      DEC_PARTITION(mi_row, this_mi_col, subsize, 0);
2219
1.05k
      this_mi_col += ebs_w;
2220
1.05k
      DEC_PARTITION(mi_row, this_mi_col, bsize_big, 1);
2221
1.05k
      this_mi_col += 4 * ebs_w;
2222
1.05k
      DEC_PARTITION(mi_row, this_mi_col, bsize_med, 2);
2223
1.05k
      this_mi_col += 2 * ebs_w;
2224
1.05k
      DEC_PARTITION(mi_row, this_mi_col, subsize, 3);
2225
1.05k
      break;
2226
0
    }
2227
15.1k
    case PARTITION_HORZ_3:
2228
30.6k
    case PARTITION_VERT_3: {
2229
150k
      for (int i = 0; i < 4; ++i) {
2230
119k
        BLOCK_SIZE this_bsize = get_h_partition_subsize(bsize, i, partition);
2231
119k
        const int offset_r = get_h_partition_offset_mi_row(bsize, i, partition);
2232
119k
        const int offset_c = get_h_partition_offset_mi_col(bsize, i, partition);
2233
2234
119k
        assert(this_bsize != BLOCK_INVALID);
2235
119k
        assert(offset_r >= 0 && offset_c >= 0);
2236
2237
119k
        const int this_mi_row = mi_row + offset_r;
2238
119k
        const int this_mi_col = mi_col + offset_c;
2239
2240
119k
        DEC_PARTITION(this_mi_row, this_mi_col, this_bsize, i);
2241
119k
      }
2242
30.6k
      break;
2243
15.1k
    }
2244
24.0k
    case PARTITION_SPLIT:
2245
24.0k
      DEC_PARTITION(mi_row, mi_col, subsize, 0);
2246
24.0k
      DEC_PARTITION(mi_row, mi_col + hbs_w, subsize, 1);
2247
24.0k
      DEC_PARTITION(mi_row + hbs_h, mi_col, subsize, 2);
2248
24.0k
      DEC_PARTITION(mi_row + hbs_h, mi_col + hbs_w, subsize, 3);
2249
24.0k
      break;
2250
0
    default: assert(0 && "Invalid partition type");
2251
2.04M
  }
2252
2253
2.01M
  PARTITION_TREE *parent = ptree->parent;
2254
2.01M
  if (!is_sb_root && parent) {
2255
1.85M
    if (!frame_is_intra_only(cm) && !cm->seq_params.monochrome &&
2256
0
        ptree->partition && parent->region_type != INTRA_REGION &&
2257
0
        ptree->region_type == INTRA_REGION) {
2258
      // decode chroma part in one intra region
2259
0
      xd->tree_type = CHROMA_PART;
2260
0
      DEC_BLOCK(mi_row, mi_col, bsize, 0);
2261
      // reset back to shared part
2262
0
      xd->tree_type = SHARED_PART;
2263
0
    }
2264
1.85M
  }
2265
2266
2.01M
#undef DEC_PARTITION
2267
2.01M
#undef DEC_BLOCK
2268
2.01M
#undef DEC_BLOCK_EPT_ARG
2269
2.01M
#undef DEC_BLOCK_STX_ARG
2270
2271
2.01M
  if (parse_decode_flag & 1) {
2272
2.01M
    update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize, partition);
2273
2.01M
    if (is_intra_sdp_enabled && xd->tree_type == SHARED_PART) {
2274
33.0k
      xd->tree_type = CHROMA_PART;
2275
33.0k
      update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
2276
33.0k
                                   partition);
2277
33.0k
      xd->tree_type = SHARED_PART;
2278
33.0k
    }
2279
2.01M
  }
2280
2.01M
}
2281
2282
static AVM_INLINE void setup_bool_decoder(
2283
    const uint8_t *data, const uint8_t *data_end, const size_t read_size,
2284
    struct avm_internal_error_info *error_info, avm_reader *r,
2285
29.3k
    uint8_t allow_update_cdf) {
2286
  // Validate the calculated partition length. If the buffer
2287
  // described by the partition can't be fully read, then restrict
2288
  // it to the portion that can be (for EC mode) or throw an error.
2289
29.3k
  if (!read_is_valid(data, read_size, data_end))
2290
0
    avm_internal_error(error_info, AVM_CODEC_CORRUPT_FRAME,
2291
0
                       "Truncated packet or corrupt tile length");
2292
2293
29.3k
  if (avm_reader_init(r, data, read_size))
2294
0
    avm_internal_error(error_info, AVM_CODEC_MEM_ERROR,
2295
0
                       "Failed to allocate bool decoder %d", 1);
2296
2297
29.3k
  r->allow_update_cdf = allow_update_cdf;
2298
29.3k
}
2299
2300
static AVM_INLINE void decode_partition_sb(AV2Decoder *const pbi,
2301
                                           ThreadData *const td, int mi_row,
2302
                                           int mi_col, avm_reader *reader,
2303
                                           BLOCK_SIZE bsize,
2304
139k
                                           int parse_decode_flag) {
2305
139k
  assert(bsize < BLOCK_SIZES_ALL);
2306
139k
  AV2_COMMON *const cm = &pbi->common;
2307
139k
  DecoderCodingBlock *const dcb = &td->dcb;
2308
139k
  MACROBLOCKD *const xd = &dcb->xd;
2309
139k
  xd->tree_type = SHARED_PART;
2310
139k
  const int is_intra_sdp_enabled = is_sdp_enabled_in_keyframe(cm);
2311
2312
139k
  if (parse_decode_flag & 1) {
2313
139k
    av2_reset_ptree_in_sbi(xd->sbi, xd->tree_type);
2314
139k
    if (is_intra_sdp_enabled) av2_reset_ptree_in_sbi(xd->sbi, CHROMA_PART);
2315
139k
  }
2316
139k
  decode_partition(
2317
139k
      pbi, td, mi_row, mi_col, reader, bsize, xd->sbi,
2318
139k
      td->dcb.xd.sbi->ptree_root[av2_get_sdp_idx(xd->tree_type)],
2319
139k
      (is_intra_sdp_enabled ? td->dcb.xd.sbi->ptree_root[1] : NULL),
2320
139k
      parse_decode_flag);
2321
2322
139k
  if ((cm->bru.enabled && cm->current_frame.frame_type != KEY_FRAME) ||
2323
133k
      cm->bridge_frame_info.is_bridge_frame) {
2324
0
    if (pbi->bru_opt_mode && !cm->bridge_frame_info.is_bridge_frame) {
2325
0
      if (bru_is_sb_available(cm, mi_col, mi_row)) {
2326
#ifndef NDEBUG
2327
        RefCntBuffer *ref_buf = get_ref_frame_buf(cm, cm->bru.update_ref_idx);
2328
        assert(ref_buf != NULL);
2329
#endif
2330
        // for active sb, update to bru ref
2331
        // for support sb, prepare copy to cur_frame (prepare for intra)
2332
0
        if (bru_is_sb_active(cm, mi_col, mi_row))
2333
0
          bru_update_sb(cm, mi_col, mi_row);
2334
0
        else
2335
0
          bru_copy_sb(cm, mi_col, mi_row);
2336
0
      }
2337
0
    } else {
2338
0
      if (!bru_is_sb_active(cm, mi_col, mi_row) ||
2339
0
          cm->bridge_frame_info.is_bridge_frame) {
2340
0
        if (cm->seq_params.order_hint_info.enable_ref_frame_mvs) {
2341
0
          const int sb_size = cm->seq_params.sb_size;
2342
          // set cur_frame mvs to 0
2343
0
          const int w = mi_size_wide[sb_size];
2344
0
          const int h = mi_size_high[sb_size];
2345
0
          const int x_inside_boundary =
2346
0
              AVMMIN(w, cm->mi_params.mi_cols - mi_col) << MI_SIZE_LOG2;
2347
0
          const int y_inside_boundary =
2348
0
              AVMMIN(h, cm->mi_params.mi_rows - mi_row) << MI_SIZE_LOG2;
2349
0
          bru_zero_sb_mvs(cm, -1, mi_row, mi_col,
2350
0
                          x_inside_boundary >> MI_SIZE_LOG2,
2351
0
                          y_inside_boundary >> MI_SIZE_LOG2);
2352
0
        }
2353
0
      }
2354
0
    }
2355
0
  }
2356
#if CONFIG_INSPECTION
2357
  if (pbi->inspect_sb_cb != NULL) {
2358
    (*pbi->inspect_sb_cb)(pbi, pbi->inspect_ctx);
2359
  }
2360
#endif  // CONFIG_INSPECTION
2361
139k
}
2362
static AVM_INLINE void setup_bru_active_info(AV2_COMMON *const cm,
2363
0
                                             struct avm_read_bit_buffer *rb) {
2364
0
  init_bru_params(cm);
2365
0
  if (cm->current_frame.frame_type != INTER_FRAME) {
2366
0
    return;
2367
0
  }
2368
0
  if (cm->bridge_frame_info.is_bridge_frame) {
2369
0
    return;
2370
0
  }
2371
  // need to refresh bru.active_mode_map every frame
2372
0
  memset(cm->bru.active_mode_map, 2, sizeof(uint8_t) * cm->bru.total_units);
2373
0
  if (cm->seq_params.enable_bru) {
2374
0
    cm->bru.enabled = avm_rb_read_bit(rb);
2375
0
    if (cm->bru.enabled) {
2376
0
      memset(cm->bru.active_mode_map, 0, sizeof(uint8_t) * cm->bru.total_units);
2377
0
      cm->bru.update_ref_idx = avm_rb_read_literal(
2378
0
          rb, avm_ceil_log2(cm->ref_frames_info.num_total_refs));
2379
0
      cm->bru.frame_inactive_flag = avm_rb_read_bit(rb);
2380
0
      if (cm->bru.frame_inactive_flag) {
2381
0
        cm->features.disable_cdf_update = 1;
2382
0
      }
2383
0
      if (!cm->immediate_output_picture) {
2384
0
        avm_internal_error(&cm->error, AVM_CODEC_ERROR,
2385
0
                           "Invalid immediate_output_picture: BRU frame must "
2386
0
                           "be immediate_output_picture");
2387
0
      }
2388
0
    }
2389
0
  }
2390
0
}
2391
2392
static void read_seg_syntax_info_to_segmentation(
2393
8.63k
    struct segmentation *seg, struct avm_read_bit_buffer *rb) {
2394
8.63k
  const int max_seg_num = seg->enable_ext_seg ? MAX_SEGMENTS : MAX_SEGMENTS_8;
2395
8.63k
  av2_clearall_segfeatures(seg);
2396
2397
78.0k
  for (int i = 0; i < max_seg_num; i++) {
2398
277k
    for (int j = 0; j < SEG_LVL_MAX; j++) {
2399
208k
      int data = 0;
2400
208k
      const int feature_enabled = avm_rb_read_bit(rb);
2401
208k
      if (feature_enabled) {
2402
111k
        av2_enable_segfeature(seg, i, j);
2403
111k
        const int data_max = av2_seg_feature_data_max(j);
2404
111k
        const int data_min = -data_max;
2405
111k
        const int ubits = get_unsigned_bits(data_max);
2406
2407
111k
        if (av2_is_segfeature_signed(j)) {
2408
31.8k
          data = avm_rb_read_inv_signed_literal(rb, ubits);
2409
79.4k
        } else {
2410
79.4k
          data = avm_rb_read_literal(rb, ubits);
2411
79.4k
        }
2412
111k
        data = clamp(data, data_min, data_max);
2413
111k
      }
2414
208k
      av2_set_segdata(seg, i, j, data);
2415
208k
    }
2416
69.4k
  }
2417
2418
8.63k
  av2_calculate_segdata(seg);
2419
8.63k
}
2420
2421
static AVM_INLINE void setup_segmentation(AV2_COMMON *const cm,
2422
16.3k
                                          struct avm_read_bit_buffer *rb) {
2423
16.3k
  struct segmentation *const seg = &cm->seg;
2424
2425
16.3k
  seg->update_map = 0;
2426
16.3k
  seg->update_data = 0;
2427
16.3k
  seg->temporal_update = 0;
2428
16.3k
  seg->enable_ext_seg = cm->seq_params.enable_ext_seg;
2429
2430
16.3k
  seg->enabled = avm_rb_read_bit(rb);
2431
16.3k
  if (!seg->enabled) {
2432
7.72k
    if (cm->cur_frame->seg_map) {
2433
7.72k
      memset(cm->cur_frame->seg_map, 0,
2434
7.72k
             (cm->cur_frame->mi_rows * cm->cur_frame->mi_cols));
2435
7.72k
    }
2436
2437
7.72k
    memset(seg, 0, sizeof(*seg));
2438
7.72k
    seg->enable_ext_seg = cm->seq_params.enable_ext_seg;
2439
7.72k
    segfeatures_copy(&cm->cur_frame->seg, seg);
2440
7.72k
    return;
2441
7.72k
  }
2442
2443
8.65k
  if (cm->seg.enabled && cm->prev_frame &&
2444
0
      (cm->mi_params.mi_rows == cm->prev_frame->mi_rows) &&
2445
0
      (cm->mi_params.mi_cols == cm->prev_frame->mi_cols)) {
2446
0
    cm->last_frame_seg_map = cm->prev_frame->seg_map;
2447
8.65k
  } else {
2448
8.65k
    cm->last_frame_seg_map = NULL;
2449
8.65k
  }
2450
2451
8.65k
  const SegmentationInfoSyntax *const seg_params =
2452
8.65k
      find_effective_seg_params(cm);
2453
8.65k
  int reuse = 0;
2454
8.65k
  if (seg_params && is_frame_seg_config_reuse_eligible(seg_params, seg)) {
2455
20
    if (seg_params->allow_seg_info_change) {
2456
0
      reuse = avm_rb_read_bit(rb);
2457
20
    } else {
2458
20
      reuse = 1;
2459
20
    }
2460
20
  }
2461
2462
8.65k
  if (reuse) {
2463
20
    av2_reconstruct_seg_params(seg_params, seg);
2464
8.63k
  } else {
2465
8.63k
    read_seg_syntax_info_to_segmentation(seg, rb);
2466
8.63k
  }
2467
2468
8.65k
  if (cm->features.derived_primary_ref_frame == PRIMARY_REF_NONE) {
2469
    // These frames can't use previous frames, so must signal map + features
2470
8.65k
    seg->update_map = 1;
2471
8.65k
    seg->temporal_update = 0;
2472
8.65k
    seg->update_data = 1;
2473
8.65k
    seg->enable_ext_seg = cm->seq_params.enable_ext_seg;
2474
8.65k
  } else {
2475
0
    seg->update_map = avm_rb_read_bit(rb);
2476
0
    if (seg->update_map) {
2477
0
      if (cm->current_frame.frame_type == S_FRAME)
2478
0
        seg->temporal_update = 0;
2479
0
      else
2480
0
        seg->temporal_update = avm_rb_read_bit(rb);
2481
0
    } else {
2482
0
      seg->temporal_update = 0;
2483
0
    }
2484
0
    seg->update_data = reuse ? 0 : 1;
2485
0
  }
2486
8.65k
}
2487
2488
// Same function as av2_read_uniform but reading from uncompressed header rb
2489
79.6k
static int rb_read_uniform(struct avm_read_bit_buffer *const rb, int n) {
2490
79.6k
  const int l = get_unsigned_bits(n);
2491
79.6k
  const int m = (1 << l) - n;
2492
79.6k
  const int v = avm_rb_read_literal(rb, l - 1);
2493
79.6k
  assert(l != 0);
2494
79.6k
  if (v < m)
2495
63.9k
    return v;
2496
15.6k
  else
2497
15.6k
    return (v << 1) - m + avm_rb_read_bit(rb);
2498
79.6k
}
2499
2500
// Converts decoded index to frame restoration type depending on lr tools
2501
// that are enabled for the frame for a given plane.
2502
static RestorationType index_to_frame_restoration_type(
2503
45.7k
    const AV2_COMMON *const cm, int plane, int ndx) {
2504
45.7k
  RestorationType r = RESTORE_NONE;
2505
95.7k
  for (r = RESTORE_NONE; r < RESTORE_TYPES; ++r) {
2506
95.7k
    if (((cm->features.lr_tools_disable_mask[plane] >> r) & 1) == 0) {
2507
87.4k
      ndx--;
2508
87.4k
      if (ndx < 0) break;
2509
87.4k
    }
2510
95.7k
  }
2511
45.7k
  assert(r < RESTORE_TYPES);
2512
45.7k
  return r;
2513
45.7k
}
2514
2515
static AVM_INLINE void decode_restoration_mode(AV2_COMMON *cm,
2516
15.6k
                                               struct avm_read_bit_buffer *rb) {
2517
15.6k
  assert(!cm->features.all_lossless);
2518
15.6k
  const int num_planes = av2_num_planes(cm);
2519
15.6k
  int luma_none = 1, chroma_none = 1;
2520
61.3k
  for (int p = 0; p < num_planes; ++p) {
2521
45.7k
    RestorationInfo *rsi = &cm->rst_info[p];
2522
45.7k
    rsi->frame_filters_on = 0;
2523
45.7k
    cm->cur_frame->rst_info[p].frame_filters_on = 0;
2524
45.7k
    rsi->temporal_pred_flag = 0;
2525
45.7k
    cm->cur_frame->rst_info[p].temporal_pred_flag = 0;
2526
45.7k
    if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame ||
2527
45.7k
        cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
2528
0
      rsi->frame_restoration_type = RESTORE_NONE;
2529
0
      continue;
2530
0
    }
2531
45.7k
    uint8_t plane_lr_tools_disable_mask =
2532
45.7k
        cm->seq_params.lr_tools_disable_mask[p > 0];
2533
45.7k
    av2_set_lr_tools(plane_lr_tools_disable_mask, p, &cm->features);
2534
45.7k
    const int ndx = rb_read_uniform(rb, cm->features.lr_frame_tools_count[p]);
2535
45.7k
    rsi->frame_restoration_type = index_to_frame_restoration_type(cm, p, ndx);
2536
45.7k
    if (rsi->frame_restoration_type != RESTORE_NONE) {
2537
20.6k
      luma_none &= p > 0;
2538
20.6k
      chroma_none &= p == 0;
2539
20.6k
    }
2540
45.7k
    const int is_wiener_nonsep_possible =
2541
45.7k
        rsi->frame_restoration_type == RESTORE_WIENER_NONSEP ||
2542
34.4k
        rsi->frame_restoration_type == RESTORE_SWITCHABLE;
2543
45.7k
    if (is_wiener_nonsep_possible) {
2544
20.3k
      rsi->frame_filters_initialized = 0;
2545
20.3k
      if (is_frame_filters_enabled(p)) {
2546
20.3k
        rsi->frame_filters_on = avm_rb_read_bit(rb);
2547
20.3k
        rsi->rst_ref_pic_idx = 0;
2548
20.3k
        rsi->temporal_pred_flag = 0;
2549
20.3k
        if (rsi->frame_filters_on) {
2550
10.3k
          const int num_ref_frames =
2551
10.3k
              (frame_is_intra_only(cm) || frame_is_sframe(cm))
2552
10.3k
                  ? 0
2553
10.3k
                  : cm->ref_frames_info.num_total_refs;
2554
2555
10.3k
          if (num_ref_frames > 0) rsi->temporal_pred_flag = avm_rb_read_bit(rb);
2556
10.3k
          int num_ref_frames_available = 0;
2557
10.3k
          for (int i = 0; i < num_ref_frames; i++) {
2558
0
            if (cm->ref_frame_map[cm->remapped_ref_idx[i]] != NULL)
2559
0
              num_ref_frames_available +=
2560
0
                  !cm->ref_frame_map[cm->remapped_ref_idx[i]]->is_restricted;
2561
0
          }
2562
10.3k
          if (num_ref_frames_available == 0)
2563
10.3k
            assert(rsi->temporal_pred_flag == 0);
2564
10.3k
          if (rsi->temporal_pred_flag && num_ref_frames > 1) {
2565
0
            rsi->rst_ref_pic_idx = avm_rb_read_literal(
2566
0
                rb,
2567
0
                avm_ceil_log2(num_ref_frames));  // read_lr_reference_idx
2568
0
            if (get_ref_frame_buf(cm, rsi->rst_ref_pic_idx)->is_restricted) {
2569
0
              avm_internal_error(
2570
0
                  &cm->error, AVM_CODEC_ERROR,
2571
0
                  "Invalid rst_ref_pic_idx: restricted reference buffer");
2572
0
            }
2573
0
          }
2574
10.3k
        }
2575
2576
20.3k
        if (rsi->temporal_pred_flag) {
2577
0
          RestorationInfo tmp_rsi =
2578
0
              get_ref_frame_buf(cm, rsi->rst_ref_pic_idx)->rst_info[p];
2579
0
          if (!tmp_rsi.frame_filters_on) {
2580
0
            const int alternate_plane = alternate_ref_plane(p);
2581
0
            assert(alternate_plane != -1);
2582
0
            tmp_rsi = get_ref_frame_buf(cm, rsi->rst_ref_pic_idx)
2583
0
                          ->rst_info[alternate_plane];
2584
0
          }
2585
0
          if (!tmp_rsi.frame_filters_on) {
2586
0
            avm_internal_error(
2587
0
                &cm->error, AVM_CODEC_ERROR,
2588
0
                "Invalid rst_ref_pic_idx: ref frame frame filter disabled");
2589
0
          }
2590
0
          av2_copy_rst_frame_filters(rsi, &tmp_rsi);
2591
0
          rsi->frame_filters_initialized = 1;
2592
2593
0
          av2_copy_rst_frame_filters(&cm->cur_frame->rst_info[p], rsi);
2594
20.3k
        } else {
2595
20.3k
          if (rsi->frame_filters_on && max_num_classes(p) > 1) {
2596
8.91k
            rsi->num_filter_classes = decode_num_filter_classes(
2597
8.91k
                avm_rb_read_literal(rb, NUM_FILTER_CLASSES_BITS));
2598
8.91k
          } else
2599
11.4k
            rsi->num_filter_classes = 1;
2600
20.3k
        }
2601
20.3k
      } else {
2602
0
        rsi->frame_filters_on = 0;
2603
0
        rsi->num_filter_classes = NUM_WIENERNS_CLASS_INIT_CHROMA;
2604
0
      }
2605
20.3k
    }
2606
45.7k
    assert(IMPLIES(!rsi->frame_filters_on, !rsi->temporal_pred_flag));
2607
45.7k
  }
2608
15.6k
  int subsampling_xy =
2609
15.6k
      AVMMAX(cm->seq_params.subsampling_x, cm->seq_params.subsampling_y);
2610
2611
15.6k
  cm->rst_info[0].restoration_unit_size = RESTORATION_UNITSIZE_MAX >> 3;
2612
15.6k
  cm->rst_info[1].restoration_unit_size =
2613
15.6k
      RESTORATION_UNITSIZE_MAX >> (3 + subsampling_xy);
2614
15.6k
  cm->rst_info[2].restoration_unit_size = cm->rst_info[1].restoration_unit_size;
2615
2616
15.6k
  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) {
2617
0
    if (num_planes > 1) {
2618
0
      cm->rst_info[1].restoration_unit_size =
2619
0
          RESTORATION_UNITSIZE_MAX >> (3 + subsampling_xy);
2620
0
      cm->rst_info[2].restoration_unit_size =
2621
0
          cm->rst_info[1].restoration_unit_size;
2622
0
    }
2623
0
    return;
2624
0
  }
2625
2626
15.6k
  if (!luma_none) {
2627
12.3k
    int size = RESTORATION_UNITSIZE_MAX;
2628
12.3k
    if (avm_rb_read_bit(rb))
2629
1.14k
      cm->rst_info[0].restoration_unit_size = size >> 1;
2630
11.2k
    else {
2631
11.2k
      if (cm->mib_size == 64) {  // sb_szie == 256
2632
0
        cm->rst_info[0].restoration_unit_size = size;
2633
11.2k
      } else {
2634
11.2k
        if (avm_rb_read_bit(rb))
2635
9
          cm->rst_info[0].restoration_unit_size = size;
2636
11.2k
        else {
2637
11.2k
          if (cm->mib_size == 32) {  // sb_szie == 128
2638
21
            cm->rst_info[0].restoration_unit_size = size >> 2;
2639
11.2k
          } else {
2640
11.2k
            if (avm_rb_read_bit(rb))
2641
202
              cm->rst_info[0].restoration_unit_size = size >> 2;
2642
11.0k
            else
2643
11.0k
              cm->rst_info[0].restoration_unit_size = size >> 3;
2644
11.2k
          }
2645
11.2k
        }
2646
11.2k
      }
2647
11.2k
    }
2648
12.3k
  }
2649
15.6k
  if (num_planes > 1) {
2650
15.0k
    if (!chroma_none) {
2651
7.60k
      int size = RESTORATION_UNITSIZE_MAX >> subsampling_xy;
2652
7.60k
      if (avm_rb_read_bit(rb))
2653
650
        cm->rst_info[1].restoration_unit_size = size >> 1;
2654
6.95k
      else {
2655
6.95k
        if (cm->mib_size == 64) {  // sb_szie == 256
2656
0
          cm->rst_info[1].restoration_unit_size = size;
2657
6.95k
        } else {
2658
6.95k
          if (avm_rb_read_bit(rb))
2659
20
            cm->rst_info[1].restoration_unit_size = size;
2660
6.93k
          else {
2661
6.93k
            if (cm->mib_size == 32) {  // sb_szie == 128
2662
45
              cm->rst_info[1].restoration_unit_size = size >> 2;
2663
6.88k
            } else {
2664
6.88k
              if (avm_rb_read_bit(rb))
2665
4
                cm->rst_info[1].restoration_unit_size = size >> 2;
2666
6.88k
              else
2667
6.88k
                cm->rst_info[1].restoration_unit_size = size >> 3;
2668
6.88k
            }
2669
6.93k
          }
2670
6.95k
        }
2671
6.95k
      }
2672
      // ru_size can be not smaller than stripe size, this error could only be
2673
      // triggered for 422 coding.
2674
7.60k
      if (cm->rst_info[1].restoration_unit_size <
2675
7.60k
          (64 >> cm->seq_params.subsampling_y)) {
2676
0
        avm_internal_error(&cm->error, AVM_CODEC_ERROR,
2677
0
                           "Invalid RU size, RU size shall not be smaller than "
2678
0
                           "stripe height which is 64 for 422 format");
2679
0
        return;
2680
0
      }
2681
7.60k
    }
2682
15.0k
    cm->rst_info[2].restoration_unit_size =
2683
15.0k
        cm->rst_info[1].restoration_unit_size;
2684
15.0k
  }
2685
2686
  // add the normative restriction of ru size so that a RU shall not cross any
2687
  // tile boundaries
2688
15.6k
  int max_plane_ru_size =
2689
15.6k
      AVMMAX(cm->rst_info[0].restoration_unit_size,
2690
15.6k
             cm->rst_info[1].restoration_unit_size << subsampling_xy);
2691
21.5k
  for (int tile_col = 0; tile_col < cm->tiles.cols - 1; tile_col++) {
2692
5.96k
    int tile_w = (cm->tiles.col_start_sb[tile_col + 1] -
2693
5.96k
                  cm->tiles.col_start_sb[tile_col])
2694
5.96k
                 << (cm->mib_size_log2 + MI_SIZE_LOG2);
2695
5.96k
    if (tile_w % max_plane_ru_size) {
2696
0
      avm_internal_error(
2697
0
          &cm->error, AVM_CODEC_ERROR,
2698
0
          "Invalid RU size, RU size shall be an integer divisor of tiles "
2699
0
          "width or height, except right-most and bottom tiles");
2700
0
      return;
2701
0
    }
2702
5.96k
  }
2703
2704
23.2k
  for (int tile_row = 0; tile_row < cm->tiles.rows - 1; tile_row++) {
2705
7.63k
    int tile_h = (cm->tiles.row_start_sb[tile_row + 1] -
2706
7.63k
                  cm->tiles.row_start_sb[tile_row])
2707
7.63k
                 << (cm->mib_size_log2 + MI_SIZE_LOG2);
2708
7.63k
    if (tile_h % max_plane_ru_size) {
2709
14
      avm_internal_error(
2710
14
          &cm->error, AVM_CODEC_ERROR,
2711
14
          "Invalid RU size, RU size shall be an integer divisor of tiles "
2712
14
          "width or height, except right-most and bottom tiles");
2713
14
      return;
2714
14
    }
2715
7.63k
  }
2716
2717
47.6k
  for (int p = 0; p < num_planes; ++p) {
2718
32.0k
    if (is_frame_filters_enabled(p) &&
2719
32.0k
        to_readwrite_framefilters(&cm->rst_info[p], 0, 0)) {
2720
9.76k
      read_wienerns_framefilters_hdr(cm, p, rb);
2721
9.76k
    }
2722
32.0k
  }
2723
15.5k
}
2724
2725
// Decodes match indices.
2726
static void read_match_indices_hdr(int plane, WienerNonsepInfo *wienerns_info,
2727
9.76k
                                   struct avm_read_bit_buffer *rb, int nopcw) {
2728
9.76k
  assert(NUM_MATCH_GROUPS == 3);
2729
9.76k
  int group_counts[NUM_MATCH_GROUPS];
2730
9.76k
  set_group_counts(plane, wienerns_info->num_classes,
2731
9.76k
                   wienerns_info->num_ref_filters, group_counts, nopcw);
2732
96.6k
  for (int c_id = 0; c_id < wienerns_info->num_classes; ++c_id) {
2733
    // Read group-id.
2734
86.8k
    int only;
2735
86.8k
    const int pred_group =
2736
86.8k
        predict_group(c_id, wienerns_info->match_indices, group_counts, &only);
2737
86.8k
    int group = 0;
2738
86.8k
    int group_bit = only ? 0 : avm_rb_read_bit(rb);
2739
86.8k
    if (group_bit == 0) {
2740
      // group-id matches prediction.
2741
64.5k
      group = pred_group;
2742
64.5k
    } else {
2743
22.3k
      int zero_group = -1;
2744
44.6k
      for (int i = 0; i < NUM_MATCH_GROUPS; ++i) {
2745
44.6k
        if (i == pred_group) continue;
2746
43.5k
        if (group_counts[i] == 0) {
2747
          // There is a group-id with zero count.
2748
22.3k
          zero_group = i;
2749
22.3k
          break;
2750
22.3k
        }
2751
43.5k
      }
2752
22.3k
      if (zero_group != -1) {
2753
        // group-id is the remaining non-zero group.
2754
22.3k
        group = 3 - (pred_group + zero_group);
2755
22.3k
      } else {
2756
0
        const int convert_larger[] = { 2, 2, 1 };
2757
0
        const int convert_smaller[] = { 1, 0, 0 };
2758
0
        group_bit = avm_rb_read_bit(rb);
2759
        // Infer group-id around pred_group.
2760
0
        if (group_bit) {
2761
0
          group = convert_larger[pred_group];
2762
0
        } else {
2763
0
          group = convert_smaller[pred_group];
2764
0
        }
2765
0
      }
2766
22.3k
    }
2767
    // Decode match index with known group-id.
2768
86.8k
    const int ref = predict_within_group(
2769
86.8k
        group, c_id, wienerns_info->match_indices, group_counts);
2770
86.8k
    const int base = get_group_base(group, group_counts);
2771
86.8k
    const int n = group == 0 ? c_id + 1 : group_counts[group];
2772
86.8k
    int decoded_match = base;
2773
86.8k
    if (n > 1) {
2774
85.7k
      decoded_match +=
2775
85.7k
          (int)avm_rb_read_primitive_refsubexpfin(rb, n, 4, ref - base);
2776
85.7k
    }
2777
2778
86.8k
    wienerns_info->match_indices[c_id] = decoded_match;
2779
86.8k
  }
2780
9.76k
}
2781
2782
// Read frame level wiener filters from the uncompressed frame header
2783
static void read_wienerns_framefilters_hdr(AV2_COMMON *cm, int plane,
2784
9.76k
                                           struct avm_read_bit_buffer *rb) {
2785
9.76k
  const int base_qindex = cm->quant_params.base_qindex;
2786
9.76k
  const int is_uv = plane != AVM_PLANE_Y;
2787
9.76k
  const int nopcw = disable_pcwiener_filters_in_framefilters(&cm->seq_params);
2788
9.76k
  RestorationInfo *rsi = &cm->rst_info[plane];
2789
9.76k
  assert(is_frame_filters_enabled(plane));
2790
9.76k
  assert(rsi->frame_filters_on && !rsi->frame_filters_initialized);
2791
9.76k
  if (cm->frame_filter_dictionary == NULL) {
2792
222
    allocate_frame_filter_dictionary(cm);
2793
222
    translate_pcwiener_filters_to_wienerns(cm);
2794
222
  }
2795
9.76k
  *cm->num_ref_filters = set_frame_filter_dictionary(
2796
9.76k
      plane, cm, rsi->num_filter_classes, cm->frame_filter_dictionary,
2797
9.76k
      cm->frame_filter_dictionary_stride);
2798
9.76k
  int16_t *frame_filter_dictionary = cm->frame_filter_dictionary;
2799
9.76k
  const int dict_stride = cm->frame_filter_dictionary_stride;
2800
9.76k
  assert(frame_filter_dictionary != NULL);
2801
9.76k
  assert(dict_stride > 0);
2802
2803
9.76k
  int skip_filter_read_for_class[WIENERNS_MAX_CLASSES] = { 0 };
2804
9.76k
  const int num_classes = rsi->num_filter_classes;
2805
9.76k
  rsi->frame_filters.num_classes = num_classes;
2806
9.76k
  rsi->frame_filters.num_ref_filters = *cm->num_ref_filters;
2807
9.76k
  assert(num_classes <= WIENERNS_MAX_CLASSES);
2808
9.76k
  assert(!rsi->temporal_pred_flag);
2809
2810
9.76k
  read_match_indices_hdr(plane, &rsi->frame_filters, rb, nopcw);
2811
2812
96.6k
  for (int c_id = 0; c_id < num_classes; ++c_id) {
2813
86.8k
    const int exact_match = avm_rb_read_bit(rb);
2814
86.8k
    skip_filter_read_for_class[c_id] = exact_match;
2815
86.8k
  }
2816
9.76k
  const WienernsFilterParameters *nsfilter_params =
2817
9.76k
      get_wienerns_parameters(base_qindex, is_uv);
2818
9.76k
  const int(*wienerns_coeffs)[WIENERNS_COEFCFG_LEN] = nsfilter_params->coeffs;
2819
9.76k
  WienerNonsepInfoBank bank = { 0 };
2820
9.76k
  bank.filter[0].num_classes = num_classes;
2821
41.3k
  for (int c_id = 0; c_id < num_classes; ++c_id) {
2822
31.5k
    fill_first_slot_of_bank_with_filter_match(
2823
31.5k
        plane, &bank, &rsi->frame_filters, rsi->frame_filters.match_indices,
2824
31.5k
        base_qindex, c_id, frame_filter_dictionary, dict_stride, nopcw);
2825
31.5k
    if (skip_filter_read_for_class[c_id]) {
2826
966
      copy_nsfilter_taps_for_class(
2827
966
          &rsi->frame_filters, av2_constref_from_wienerns_bank(&bank, 0, c_id),
2828
966
          c_id);
2829
966
      continue;
2830
966
    }
2831
30.6k
    const WienerNonsepInfo *ref_wienerns_info =
2832
30.6k
        av2_constref_from_wienerns_bank(&bank, 0, c_id);
2833
30.6k
    assert(ref_wienerns_info->num_classes == num_classes);
2834
30.6k
    int16_t *wienerns_info_nsfilter = nsfilter_taps(&rsi->frame_filters, c_id);
2835
30.6k
    const int16_t *ref_wienerns_info_nsfilter =
2836
30.6k
        const_nsfilter_taps(ref_wienerns_info, c_id);
2837
2838
30.6k
    memset(wienerns_info_nsfilter, 0,
2839
30.6k
           nsfilter_params->ncoeffs * sizeof(wienerns_info_nsfilter[0]));
2840
2841
30.6k
    const int beg_feat = 0;
2842
30.6k
    int end_feat = nsfilter_params->ncoeffs;
2843
30.6k
    int ncoeffs1, ncoeffs2;
2844
30.6k
    int ncoeffs =
2845
30.6k
        config2ncoeffs(&nsfilter_params->nsfilter_config, &ncoeffs1, &ncoeffs2);
2846
30.6k
    assert(nsfilter_params->ncoeffs == ncoeffs);
2847
30.6k
    (void)ncoeffs;
2848
30.6k
    int s = 0;
2849
31.4k
    for (int i = 0; i < nsfilter_params->nsubsets - 1; ++i) {
2850
31.3k
      const int filter_length_bit = avm_rb_read_bit(rb);
2851
31.3k
      s += filter_length_bit;
2852
31.3k
      if (!filter_length_bit) break;
2853
31.3k
    }
2854
30.6k
    assert((end_feat & 1) == 0);
2855
2856
30.6k
    int sym = 1;
2857
30.6k
    if (!skip_sym_bit(nsfilter_params, s)) {
2858
120
      assert(is_uv);
2859
120
      sym = avm_rb_read_bit(rb);
2860
120
    }
2861
2862
438k
    for (int i = beg_feat; i < end_feat; ++i) {
2863
407k
      if (!nsfilter_params->subset_config[s][i]) continue;
2864
171k
      wienerns_info_nsfilter[i] =
2865
171k
          avm_rb_read_primitive_refsubexpfin(
2866
171k
              rb, 1 << wienerns_coeffs[i - beg_feat][WIENERNS_BIT_ID],
2867
171k
              wienerns_coeffs[i - beg_feat][WIENERNS_BIT_ID] - 3,
2868
171k
              ref_wienerns_info_nsfilter[i] -
2869
171k
                  wienerns_coeffs[i - beg_feat][WIENERNS_MIN_ID]) +
2870
171k
          wienerns_coeffs[i - beg_feat][WIENERNS_MIN_ID];
2871
171k
      const int is_asym_coeff =
2872
171k
          (i < nsfilter_params->nsfilter_config.asymmetric ||
2873
164k
           (i >= ncoeffs1 &&
2874
216
            i - ncoeffs1 < nsfilter_params->nsfilter_config.asymmetric2));
2875
171k
      if (sym && is_asym_coeff) {
2876
        // Fill in symmetrical tap without reading it
2877
204
        wienerns_info_nsfilter[i + 1] = wienerns_info_nsfilter[i];
2878
204
        i++;
2879
204
      }
2880
171k
    }
2881
30.6k
  }
2882
9.76k
  rsi->frame_filters_initialized = 1;
2883
9.76k
  av2_copy_rst_frame_filters(&cm->cur_frame->rst_info[plane], rsi);
2884
9.76k
}
2885
2886
static void read_wienerns_filter(MACROBLOCKD *xd, int is_uv,
2887
                                 const RestorationInfo *rsi,
2888
                                 WienerNonsepInfo *wienerns_info,
2889
7.42k
                                 WienerNonsepInfoBank *bank, avm_reader *rb) {
2890
7.42k
  int skip_filter_read_for_class[WIENERNS_MAX_CLASSES] = { 0 };
2891
7.42k
  int ref_for_class[WIENERNS_MAX_CLASSES] = { 0 };
2892
7.42k
  const int num_classes = wienerns_info->num_classes;
2893
7.42k
  assert(num_classes <= WIENERNS_MAX_CLASSES);
2894
7.42k
  if (rsi->frame_filters_on) return;
2895
12.7k
  for (int c_id = 0; c_id < num_classes; ++c_id) {
2896
6.39k
    const int exact_match = avm_read_bit(rb, ACCT_INFO("exact_match"));
2897
6.39k
    int ref;
2898
8.80k
    for (ref = 0; ref < bank->bank_size_for_class[c_id] - 1; ++ref) {
2899
5.15k
      if (avm_read_literal(rb, 1, ACCT_INFO("bank"))) break;
2900
5.15k
    }
2901
6.39k
    wienerns_info->bank_ref_for_class[c_id] = ref;
2902
6.39k
    skip_filter_read_for_class[c_id] = exact_match;
2903
6.39k
    ref_for_class[c_id] = ref;
2904
6.39k
  }
2905
6.39k
  const WienernsFilterParameters *nsfilter_params =
2906
6.39k
      get_wienerns_parameters(xd->current_base_qindex, is_uv);
2907
6.39k
  const int(*wienerns_coeffs)[WIENERNS_COEFCFG_LEN] = nsfilter_params->coeffs;
2908
12.7k
  for (int c_id = 0; c_id < num_classes; ++c_id) {
2909
6.39k
    if (skip_filter_read_for_class[c_id]) {
2910
3.00k
      copy_nsfilter_taps_for_class(
2911
3.00k
          wienerns_info,
2912
3.00k
          av2_constref_from_wienerns_bank(bank, ref_for_class[c_id], c_id),
2913
3.00k
          c_id);
2914
3.00k
      if (bank->bank_size_for_class[c_id] == 0)
2915
1.07k
        av2_add_to_wienerns_bank(bank, wienerns_info, c_id);
2916
3.00k
      continue;
2917
3.00k
    }
2918
3.39k
    const int ref = ref_for_class[c_id];
2919
2920
3.39k
    const WienerNonsepInfo *ref_wienerns_info =
2921
3.39k
        av2_constref_from_wienerns_bank(bank, ref, c_id);
2922
3.39k
    assert(ref_wienerns_info->num_classes == num_classes);
2923
3.39k
    int16_t *wienerns_info_nsfilter = nsfilter_taps(wienerns_info, c_id);
2924
3.39k
    const int16_t *ref_wienerns_info_nsfilter =
2925
3.39k
        const_nsfilter_taps(ref_wienerns_info, c_id);
2926
2927
3.39k
    memset(wienerns_info_nsfilter, 0,
2928
3.39k
           nsfilter_params->ncoeffs * sizeof(wienerns_info_nsfilter[0]));
2929
2930
3.39k
    const int beg_feat = 0;
2931
3.39k
    int end_feat = nsfilter_params->ncoeffs;
2932
3.39k
    int ncoeffs1, ncoeffs2;
2933
3.39k
    int ncoeffs =
2934
3.39k
        config2ncoeffs(&nsfilter_params->nsfilter_config, &ncoeffs1, &ncoeffs2);
2935
3.39k
    assert(nsfilter_params->ncoeffs == ncoeffs);
2936
3.39k
    (void)ncoeffs;
2937
3.39k
    int s = 0;
2938
9.53k
    for (int i = 0; i < nsfilter_params->nsubsets - 1; ++i) {
2939
7.53k
      const int filter_length_bit =
2940
7.53k
          avm_read_symbol(rb, xd->tile_ctx->wienerns_length_cdf[is_uv], 2,
2941
7.53k
                          ACCT_INFO("wienerns_length"));
2942
7.53k
      s += filter_length_bit;
2943
7.53k
      if (!filter_length_bit) break;
2944
7.53k
    }
2945
3.39k
    assert((end_feat & 1) == 0);
2946
2947
3.39k
    int sym = 1;
2948
3.39k
    if (!skip_sym_bit(nsfilter_params, s)) {
2949
1.93k
      assert(is_uv);
2950
1.93k
      sym = avm_read_symbol(rb, xd->tile_ctx->wienerns_uv_sym_cdf, 2,
2951
1.93k
                            ACCT_INFO("wienerns_uv_sym"));
2952
1.93k
    }
2953
2954
59.4k
    for (int i = beg_feat; i < end_feat; ++i) {
2955
56.0k
      if (!nsfilter_params->subset_config[s][i]) continue;
2956
46.6k
      wienerns_info_nsfilter[i] =
2957
46.6k
          avm_read_4part_wref(
2958
46.6k
              rb,
2959
46.6k
              ref_wienerns_info_nsfilter[i] -
2960
46.6k
                  wienerns_coeffs[i - beg_feat][WIENERNS_MIN_ID],
2961
46.6k
              xd->tile_ctx->wienerns_4part_cdf
2962
46.6k
                  [wienerns_coeffs[i - beg_feat][WIENERNS_PAR_ID]],
2963
46.6k
              wienerns_coeffs[i - beg_feat][WIENERNS_BIT_ID],
2964
46.6k
              ACCT_INFO("wienerns_info_nsfilter")) +
2965
46.6k
          wienerns_coeffs[i - beg_feat][WIENERNS_MIN_ID];
2966
46.6k
      const int is_asym_coeff =
2967
46.6k
          (i < nsfilter_params->nsfilter_config.asymmetric ||
2968
46.6k
           (i >= ncoeffs1 &&
2969
18.1k
            i - ncoeffs1 < nsfilter_params->nsfilter_config.asymmetric2));
2970
46.6k
      if (sym && is_asym_coeff) {
2971
        // Fill in symmetrical tap without reading it
2972
2.48k
        wienerns_info_nsfilter[i + 1] = wienerns_info_nsfilter[i];
2973
2.48k
        i++;
2974
2.48k
      }
2975
46.6k
    }
2976
3.39k
    av2_add_to_wienerns_bank(bank, wienerns_info, c_id);
2977
3.39k
  }
2978
6.39k
}
2979
2980
static AVM_INLINE void loop_restoration_read_sb_coeffs(AV2_COMMON *cm,
2981
                                                       MACROBLOCKD *xd,
2982
                                                       avm_reader *const r,
2983
                                                       int plane,
2984
12.9k
                                                       int runit_idx) {
2985
12.9k
  RestorationInfo *rsi = &cm->rst_info[plane];
2986
12.9k
  RestorationUnitInfo *rui = &rsi->unit_info[runit_idx];
2987
12.9k
  assert(rsi->frame_restoration_type != RESTORE_NONE);
2988
2989
12.9k
  assert(!cm->features.all_lossless);
2990
2991
12.9k
  rui->wienerns_info.num_classes = rsi->num_filter_classes;
2992
2993
12.9k
  if (rsi->frame_restoration_type == RESTORE_SWITCHABLE) {
2994
532
    assert(plane == AVM_PLANE_Y);
2995
532
    rui->restoration_type = RESTORE_SWITCHABLE - 1;
2996
1.57k
    for (int re = 0; re <= RESTORE_SWITCHABLE - 2; re++) {
2997
1.06k
      if (cm->features.lr_tools_disable_mask[plane] & (1 << re)) continue;
2998
1.06k
      const int found = avm_read_symbol(
2999
1.06k
          r, xd->tile_ctx->switchable_flex_restore_cdf[re][plane], 2,
3000
1.06k
          ACCT_INFO("found"));
3001
1.06k
      if (found) {
3002
14
        rui->restoration_type = re;
3003
14
        break;
3004
14
      }
3005
1.06k
    }
3006
532
    switch (rui->restoration_type) {
3007
518
      case RESTORE_WIENER_NONSEP:
3008
518
        read_wienerns_filter(xd, plane != AVM_PLANE_Y, rsi, &rui->wienerns_info,
3009
518
                             &xd->wienerns_info[plane], r);
3010
518
        break;
3011
11
      case RESTORE_PC_WIENER:
3012
        // No side-information for now.
3013
11
        break;
3014
3
      default: assert(rui->restoration_type == RESTORE_NONE); break;
3015
532
    }
3016
12.4k
  } else if (rsi->frame_restoration_type == RESTORE_WIENER_NONSEP) {
3017
11.9k
    if (avm_read_symbol(r, xd->tile_ctx->wienerns_restore_cdf, 2,
3018
11.9k
                        ACCT_INFO("wienerns_restore_cdf"))) {
3019
6.90k
      rui->restoration_type = RESTORE_WIENER_NONSEP;
3020
6.90k
      read_wienerns_filter(xd, plane != AVM_PLANE_Y, rsi, &rui->wienerns_info,
3021
6.90k
                           &xd->wienerns_info[plane], r);
3022
6.90k
    } else {
3023
5.06k
      rui->restoration_type = RESTORE_NONE;
3024
5.06k
    }
3025
11.9k
  } else if (rsi->frame_restoration_type == RESTORE_PC_WIENER) {
3026
423
    if (avm_read_symbol(r, xd->tile_ctx->pc_wiener_restore_cdf, 2,
3027
423
                        ACCT_INFO("pc_wiener_restore_cdf"))) {
3028
103
      rui->restoration_type = RESTORE_PC_WIENER;
3029
      // No side-information for now.
3030
320
    } else {
3031
320
      rui->restoration_type = RESTORE_NONE;
3032
320
    }
3033
423
  }
3034
3035
12.9k
  assert(((cm->features.lr_tools_disable_mask[plane] >> rui->restoration_type) &
3036
12.9k
          1) == 0);
3037
12.9k
}
3038
3039
static AVM_INLINE void setup_loopfilter(AV2_COMMON *cm,
3040
16.1k
                                        struct avm_read_bit_buffer *rb) {
3041
16.1k
  CurrentFrame *const current_frame = &cm->current_frame;
3042
16.1k
  FeatureFlags *const features = &cm->features;
3043
16.1k
  const int num_planes = av2_num_planes(cm);
3044
16.1k
  struct loopfilter *lf = &cm->lf;
3045
16.1k
  if (cm->features.coded_lossless) {
3046
305
    return;
3047
305
  }
3048
16.1k
  assert(!cm->features.coded_lossless);
3049
15.7k
  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame)
3050
0
    return;
3051
15.7k
  if (current_frame->frame_type == INTER_FRAME) {
3052
0
    if (cm->seq_params.enable_lf_sub_pu) {
3053
0
      features->allow_lf_sub_pu = avm_rb_read_bit(rb);
3054
0
    }
3055
0
  }
3056
3057
15.7k
  if (features->tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
3058
0
    if (cm->seq_params.enable_lf_sub_pu && features->allow_lf_sub_pu) {
3059
0
      cm->lf.apply_deblocking_filter_tip = avm_rb_read_bit(rb);
3060
0
      if (cm->lf.apply_deblocking_filter_tip) {
3061
0
        cm->lf.tip_delta = 0;
3062
0
      }
3063
0
    }
3064
0
    return;
3065
0
  }
3066
3067
15.7k
  assert(cm->mfh_valid[cm->cur_mfh_id]);
3068
15.7k
  if (cm->mfh_params[cm->cur_mfh_id].mfh_deblocking_filter_update_flag)
3069
0
    lf->apply_deblocking_filter[0] =
3070
0
        cm->mfh_params[cm->cur_mfh_id].mfh_apply_deblocking_filter[0];
3071
15.7k
  else
3072
15.7k
    lf->apply_deblocking_filter[0] = avm_rb_read_bit(rb);
3073
15.7k
  if (cm->mfh_params[cm->cur_mfh_id].mfh_deblocking_filter_update_flag)
3074
0
    lf->apply_deblocking_filter[1] =
3075
0
        cm->mfh_params[cm->cur_mfh_id].mfh_apply_deblocking_filter[1];
3076
15.7k
  else
3077
15.7k
    lf->apply_deblocking_filter[1] = avm_rb_read_bit(rb);
3078
15.7k
  if (num_planes > 1) {
3079
15.2k
    if (lf->apply_deblocking_filter[0] || lf->apply_deblocking_filter[1]) {
3080
11.7k
      if (cm->mfh_params[cm->cur_mfh_id].mfh_deblocking_filter_update_flag) {
3081
0
        lf->apply_deblocking_filter_u =
3082
0
            cm->mfh_params[cm->cur_mfh_id].mfh_apply_deblocking_filter[2];
3083
0
        lf->apply_deblocking_filter_v =
3084
0
            cm->mfh_params[cm->cur_mfh_id].mfh_apply_deblocking_filter[3];
3085
11.7k
      } else {
3086
11.7k
        lf->apply_deblocking_filter_u = avm_rb_read_bit(rb);
3087
11.7k
        lf->apply_deblocking_filter_v = avm_rb_read_bit(rb);
3088
11.7k
      }
3089
11.7k
    } else {
3090
3.51k
      lf->apply_deblocking_filter_u = lf->apply_deblocking_filter_v = 0;
3091
3.51k
    }
3092
15.2k
  } else {
3093
523
    lf->apply_deblocking_filter_u = lf->apply_deblocking_filter_v = 0;
3094
523
  }
3095
3096
15.7k
  const uint8_t df_par_bits = cm->seq_params.df_par_bits_minus2 + 2;
3097
15.7k
  const uint8_t df_par_offset = 1 << (df_par_bits - 1);
3098
3099
15.7k
  if (lf->apply_deblocking_filter[0]) {
3100
9.14k
    int luma_delta_q = avm_rb_read_bit(rb);
3101
9.14k
    if (luma_delta_q) {
3102
1.09k
      lf->delta_q_luma[0] =
3103
1.09k
          avm_rb_read_literal(rb, df_par_bits) - df_par_offset;
3104
8.05k
    } else {
3105
8.05k
      lf->delta_q_luma[0] = 0;
3106
8.05k
    }
3107
9.14k
    lf->delta_side_luma[0] = lf->delta_q_luma[0];
3108
9.14k
  } else {
3109
6.65k
    lf->delta_q_luma[0] = 0;
3110
6.65k
    lf->delta_side_luma[0] = 0;
3111
6.65k
  }
3112
15.7k
  if (lf->apply_deblocking_filter[1]) {
3113
4.99k
    int luma_delta_q = avm_rb_read_bit(rb);
3114
4.99k
    if (luma_delta_q) {
3115
3.36k
      lf->delta_q_luma[1] =
3116
3.36k
          avm_rb_read_literal(rb, df_par_bits) - df_par_offset;
3117
3.36k
    } else {
3118
1.63k
      lf->delta_q_luma[1] = lf->delta_q_luma[0];
3119
1.63k
    }
3120
4.99k
    lf->delta_side_luma[1] = lf->delta_q_luma[1];
3121
10.7k
  } else {
3122
10.7k
    lf->delta_q_luma[1] = 0;
3123
10.7k
    lf->delta_side_luma[1] = 0;
3124
10.7k
  }
3125
3126
15.7k
  if (lf->apply_deblocking_filter_u) {
3127
8.36k
    int u_delta_q = avm_rb_read_bit(rb);
3128
8.36k
    if (u_delta_q) {
3129
7.31k
      lf->delta_q_u = avm_rb_read_literal(rb, df_par_bits) - df_par_offset;
3130
7.31k
    } else {
3131
1.05k
      lf->delta_q_u = 0;
3132
1.05k
    }
3133
8.36k
    lf->delta_side_u = lf->delta_q_u;
3134
8.36k
  } else {
3135
7.43k
    lf->delta_q_u = 0;
3136
7.43k
    lf->delta_side_u = 0;
3137
7.43k
  }
3138
15.7k
  if (lf->apply_deblocking_filter_v) {
3139
8.51k
    int v_delta_q = avm_rb_read_bit(rb);
3140
8.51k
    if (v_delta_q) {
3141
442
      lf->delta_q_v = avm_rb_read_literal(rb, df_par_bits) - df_par_offset;
3142
8.07k
    } else {
3143
8.07k
      lf->delta_q_v = 0;
3144
8.07k
    }
3145
8.51k
    lf->delta_side_v = lf->delta_q_v;
3146
8.51k
  } else {
3147
7.28k
    lf->delta_q_v = 0;
3148
7.28k
    lf->delta_side_v = 0;
3149
7.28k
  }
3150
15.7k
}
3151
3152
static AVM_INLINE void setup_gdf(AV2_COMMON *cm,
3153
15.5k
                                 struct avm_read_bit_buffer *rb) {
3154
15.5k
  cm->gdf_info.gdf_mode = 0;
3155
15.5k
  if (!is_allow_gdf(cm)) return;
3156
15.5k
  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame ||
3157
15.5k
      cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
3158
0
    return;
3159
0
  }
3160
15.5k
  init_gdf(cm);
3161
15.5k
  if (cm->seq_params.single_picture_header_flag) {
3162
15.5k
    cm->gdf_info.gdf_mode = 1;
3163
15.5k
  } else {
3164
1
    cm->gdf_info.gdf_mode = avm_rb_read_bit(rb);
3165
1
  }
3166
15.5k
  if (cm->gdf_info.gdf_mode > 0) {
3167
15.5k
    alloc_gdf_buffers(&cm->gdf_info);
3168
15.5k
    if (cm->gdf_info.gdf_block_num > 1) {
3169
15.5k
      cm->gdf_info.gdf_mode += avm_rb_read_bit(rb);
3170
15.5k
    }
3171
15.5k
    cm->gdf_info.gdf_pic_qp_idx = avm_rb_read_literal(rb, GDF_RDO_QP_NUM_LOG2);
3172
15.5k
    cm->gdf_info.gdf_pic_scale_idx =
3173
15.5k
        avm_rb_read_literal(rb, GDF_RDO_SCALE_NUM_LOG2);
3174
15.5k
  }
3175
15.5k
}
3176
3177
static AVM_INLINE void setup_cdef(AV2_COMMON *cm,
3178
15.5k
                                  struct avm_read_bit_buffer *rb) {
3179
15.5k
  const int num_planes = av2_num_planes(cm);
3180
15.5k
  CdefInfo *const cdef_info = &cm->cdef_info;
3181
15.5k
  if (cm->bridge_frame_info.is_bridge_frame) {
3182
0
    cdef_info->cdef_frame_enable = 0;
3183
0
    return;
3184
0
  }
3185
15.5k
  if (cm->bru.frame_inactive_flag ||
3186
15.5k
      cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT)
3187
0
    return;
3188
15.5k
  if (cm->seq_params.single_picture_header_flag) {
3189
15.5k
    cdef_info->cdef_frame_enable = 1;
3190
15.5k
  } else {
3191
1
    cdef_info->cdef_frame_enable = avm_rb_read_bit(rb);
3192
1
  }
3193
15.5k
  if (!cdef_info->cdef_frame_enable) {
3194
1
    cdef_info->cdef_on_skip_txfm_frame_enable = 0;
3195
1
    return;
3196
1
  }
3197
15.5k
  cdef_info->cdef_damping = avm_rb_read_literal(rb, 2) + 3;
3198
15.5k
  cdef_info->nb_cdef_strengths = avm_rb_read_literal(rb, 3) + 1;
3199
15.5k
  if (cm->seq_params.enable_cdef_on_skip_txfm == CDEF_ON_SKIP_TXFM_ADAPTIVE) {
3200
15.5k
    cdef_info->cdef_on_skip_txfm_frame_enable = avm_rb_read_bit(rb);
3201
15.5k
  } else if (cm->seq_params.enable_cdef_on_skip_txfm ==
3202
0
             CDEF_ON_SKIP_TXFM_ALWAYS_ON) {
3203
0
    cdef_info->cdef_on_skip_txfm_frame_enable = 1;
3204
0
  } else {
3205
0
    cdef_info->cdef_on_skip_txfm_frame_enable = 0;
3206
0
  }
3207
91.9k
  for (int i = 0; i < cdef_info->nb_cdef_strengths; i++) {
3208
76.3k
    int less_4 = avm_rb_read_bit(rb);
3209
76.3k
    if (less_4) {
3210
26.0k
      cdef_info->cdef_strengths[i] = avm_rb_read_literal(rb, 2);
3211
50.3k
    } else {
3212
50.3k
      cdef_info->cdef_strengths[i] =
3213
50.3k
          avm_rb_read_literal(rb, CDEF_STRENGTH_BITS);
3214
50.3k
    }
3215
3216
76.3k
    if (num_planes > 1) {
3217
74.7k
      less_4 = avm_rb_read_bit(rb);
3218
74.7k
      if (less_4) {
3219
32.1k
        cdef_info->cdef_uv_strengths[i] = avm_rb_read_literal(rb, 2);
3220
42.5k
      } else {
3221
42.5k
        cdef_info->cdef_uv_strengths[i] =
3222
42.5k
            avm_rb_read_literal(rb, CDEF_STRENGTH_BITS);
3223
42.5k
      }
3224
74.7k
    } else {
3225
1.64k
      cdef_info->cdef_uv_strengths[i] = 0;
3226
1.64k
    }
3227
76.3k
  }
3228
15.5k
}
3229
3230
// read offset idx using truncated unary coding
3231
62.8k
static AVM_INLINE int read_ccso_offset_idx(struct avm_read_bit_buffer *rb) {
3232
62.8k
  int offset_idx = 0;
3233
94.6k
  for (int idx = 0; idx < 7; ++idx) {
3234
94.4k
    const int cur_bit = avm_rb_read_bit(rb);
3235
94.4k
    if (!cur_bit) break;
3236
31.7k
    offset_idx++;
3237
31.7k
  }
3238
62.8k
  return offset_idx;
3239
62.8k
}
3240
static AVM_INLINE void setup_ccso(AV2_COMMON *cm,
3241
8.68k
                                  struct avm_read_bit_buffer *rb) {
3242
8.68k
  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame ||
3243
8.68k
      cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
3244
0
    cm->cur_frame->ccso_info.ccso_enable[0] = 0;
3245
0
    cm->cur_frame->ccso_info.ccso_enable[1] = 0;
3246
0
    cm->cur_frame->ccso_info.ccso_enable[2] = 0;
3247
0
    return;
3248
0
  }
3249
8.68k
  const int ccso_offset[8] = { 0, 1, -1, 3, -3, 7, -7, -10 };
3250
8.68k
  const int ccso_scale[4] = { 1, 2, 3, 4 };
3251
8.68k
  const int num_ref_frames = (frame_is_intra_only(cm) || frame_is_sframe(cm))
3252
8.68k
                                 ? 0
3253
8.68k
                                 : cm->ref_frames_info.num_total_refs;
3254
8.68k
  int num_ref_frames_available = 0;
3255
8.68k
  for (int i = 0; i < num_ref_frames; i++) {
3256
0
    if (cm->ref_frame_map[cm->remapped_ref_idx[i]] != NULL)
3257
0
      num_ref_frames_available +=
3258
0
          !cm->ref_frame_map[cm->remapped_ref_idx[i]]->is_restricted;
3259
0
  }
3260
8.68k
  if (cm->bridge_frame_info.is_bridge_frame) {
3261
0
    cm->ccso_info.ccso_frame_flag = 0;
3262
8.68k
  } else {
3263
8.68k
    if (cm->seq_params.single_picture_header_flag) {
3264
8.68k
      cm->ccso_info.ccso_frame_flag = 1;
3265
8.68k
    } else {
3266
1
      cm->ccso_info.ccso_frame_flag = avm_rb_read_bit(rb);
3267
1
    }
3268
8.68k
  }
3269
8.68k
  if (cm->ccso_info.ccso_frame_flag) {
3270
8.68k
    const int ccso_blk_size = get_ccso_unit_size_log2_adaptive_tile(
3271
8.68k
        cm, cm->mib_size_log2 + MI_SIZE_LOG2, CCSO_BLK_SIZE);
3272
8.68k
    cm->ccso_info.ccso_blk_size = ccso_blk_size;
3273
8.68k
    cm->cur_frame->ccso_info.ccso_blk_size = ccso_blk_size;
3274
33.1k
    for (int plane = 0; plane < av2_num_planes(cm); plane++) {
3275
24.4k
      CcsoInfo *ref_frame_ccso_info = NULL;
3276
24.4k
      cm->cur_frame->ccso_info.subsampling_y[plane] =
3277
24.4k
          plane ? cm->seq_params.subsampling_y : 0;
3278
24.4k
      cm->cur_frame->ccso_info.subsampling_x[plane] =
3279
24.4k
          plane ? cm->seq_params.subsampling_x : 0;
3280
24.4k
      cm->ccso_info.ccso_enable[plane] = avm_rb_read_bit(rb);
3281
24.4k
      if (cm->ccso_info.ccso_enable[plane]) {
3282
5.08k
        cm->cur_frame->ccso_info.ccso_enable[plane] = 1;
3283
5.08k
        if (!frame_is_intra_only(cm) && !frame_is_sframe(cm)) {
3284
0
          cm->ccso_info.reuse_ccso[plane] = avm_rb_read_bit(rb);
3285
0
          cm->ccso_info.sb_reuse_ccso[plane] = avm_rb_read_bit(rb);
3286
5.08k
        } else {
3287
5.08k
          cm->ccso_info.reuse_ccso[plane] = 0;
3288
5.08k
          cm->ccso_info.sb_reuse_ccso[plane] = 0;
3289
5.08k
        }
3290
5.08k
        if (num_ref_frames_available == 0)
3291
5.08k
          assert(cm->ccso_info.reuse_ccso[plane] == 0 &&
3292
5.08k
                 cm->ccso_info.sb_reuse_ccso[plane] == 0);
3293
5.08k
        if (cm->ccso_info.reuse_ccso[plane] ||
3294
5.08k
            cm->ccso_info.sb_reuse_ccso[plane]) {
3295
0
          if (num_ref_frames > 1) {
3296
0
            cm->ccso_info.ccso_ref_idx[plane] =
3297
0
                avm_rb_read_literal(rb, avm_ceil_log2(num_ref_frames));
3298
0
          } else {
3299
0
            cm->ccso_info.ccso_ref_idx[plane] = 0;
3300
0
          }
3301
0
          if (cm->ccso_info.ccso_ref_idx[plane] >=
3302
0
              cm->ref_frames_info.num_total_refs) {
3303
0
            avm_internal_error(
3304
0
                &cm->error, AVM_CODEC_ERROR,
3305
0
                "Invalid ccso_ref_idx: ccso_ref_idx >= num_total_refs");
3306
0
          }
3307
0
          if (get_ref_frame_buf(cm, cm->ccso_info.ccso_ref_idx[plane])
3308
0
                  ->is_restricted) {
3309
0
            avm_internal_error(&cm->error, AVM_CODEC_ERROR,
3310
0
                               "Invalid ccso_ref_idx[%d] %d: restricted "
3311
0
                               "refefence frame",
3312
0
                               plane, cm->ccso_info.ccso_ref_idx[plane]);
3313
0
          }
3314
0
          ref_frame_ccso_info =
3315
0
              &get_ref_frame_buf(cm, cm->ccso_info.ccso_ref_idx[plane])
3316
0
                   ->ccso_info;
3317
0
          if (!ref_frame_ccso_info->ccso_enable[plane]) {
3318
0
            avm_internal_error(&cm->error, AVM_CODEC_ERROR,
3319
0
                               "Invalid ccso_ref_idx: ref frame ccso disabled");
3320
0
          }
3321
0
          if (cm->ccso_info.sb_reuse_ccso[plane] &&
3322
0
              (cm->ccso_info.ccso_blk_size !=
3323
0
                   ref_frame_ccso_info->ccso_blk_size ||
3324
0
               cm->ccso_info.ccso_blk_size != CCSO_BLK_SIZE)) {
3325
0
            avm_internal_error(&cm->error, AVM_CODEC_ERROR,
3326
0
                               "Invalid ccso_reuse: ccso_blk_size mismatch");
3327
0
          }
3328
0
        }
3329
3330
5.08k
        if (cm->ccso_info.sb_reuse_ccso[plane] &&
3331
0
            ((cm->mi_params.mi_rows !=
3332
0
              get_ref_frame_buf(cm, cm->ccso_info.ccso_ref_idx[plane])
3333
0
                  ->mi_rows) ||
3334
0
             (cm->mi_params.mi_cols !=
3335
0
              get_ref_frame_buf(cm, cm->ccso_info.ccso_ref_idx[plane])
3336
0
                  ->mi_cols) ||
3337
0
             (plane && ((cm->seq_params.subsampling_y !=
3338
0
                         ref_frame_ccso_info->subsampling_y[plane]) ||
3339
0
                        (cm->seq_params.subsampling_x !=
3340
0
                         ref_frame_ccso_info->subsampling_x[plane]))))) {
3341
0
          avm_internal_error(&cm->error, AVM_CODEC_ERROR, "Invalid ccso_reuse");
3342
0
        }
3343
3344
5.08k
        if (!cm->ccso_info.reuse_ccso[plane]) {
3345
5.08k
          cm->ccso_info.ccso_bo_only[plane] = avm_rb_read_bit(rb);
3346
5.08k
          cm->ccso_info.scale_idx[plane] = avm_rb_read_literal(rb, 2);
3347
5.08k
          if (cm->ccso_info.ccso_bo_only[plane]) {
3348
1.94k
            cm->ccso_info.quant_idx[plane] = 0;
3349
1.94k
            cm->ccso_info.ext_filter_support[plane] = 0;
3350
1.94k
            cm->ccso_info.edge_clf[plane] = 0;
3351
1.94k
            cm->ccso_info.max_band_log2[plane] = avm_rb_read_literal(rb, 3);
3352
1.94k
            if (cm->ccso_info.max_band_log2[plane] >
3353
1.94k
                compute_log2(CCSO_BAND_NUM)) {
3354
188
              avm_internal_error(&cm->error, AVM_CODEC_ERROR,
3355
188
                                 "Invalid CCSO Band number");
3356
188
            }
3357
3.13k
          } else {
3358
3.13k
            cm->ccso_info.quant_idx[plane] = avm_rb_read_literal(rb, 2);
3359
3.13k
            cm->ccso_info.ext_filter_support[plane] =
3360
3.13k
                avm_rb_read_literal(rb, 3);
3361
3.13k
            if (cm->ccso_info.ext_filter_support[plane] == 7) {
3362
87
              avm_internal_error(
3363
87
                  &cm->error, AVM_CODEC_CORRUPT_FRAME,
3364
87
                  "Invalid ccso_ext_filter: ccso_ext_filter == 7");
3365
87
            }
3366
3.13k
            if (quant_sz[cm->ccso_info.scale_idx[plane]]
3367
3.13k
                        [cm->ccso_info.quant_idx[plane]]) {
3368
2.92k
              cm->ccso_info.edge_clf[plane] = avm_rb_read_bit(rb);
3369
2.92k
            } else {
3370
207
              cm->ccso_info.edge_clf[plane] = 0;
3371
207
            }
3372
3.13k
            cm->ccso_info.max_band_log2[plane] = avm_rb_read_literal(rb, 2);
3373
3.13k
          }
3374
5.08k
          const int max_band = 1 << cm->ccso_info.max_band_log2[plane];
3375
5.08k
          const int edge_clf = cm->ccso_info.edge_clf[plane];
3376
5.08k
          const int max_edge_interval = edge_clf_to_edge_interval[edge_clf];
3377
5.08k
          const int num_edge_offset_intervals =
3378
5.08k
              cm->ccso_info.ccso_bo_only[plane] ? 1 : max_edge_interval;
3379
13.9k
          for (int d0 = 0; d0 < num_edge_offset_intervals; d0++) {
3380
28.0k
            for (int d1 = 0; d1 < num_edge_offset_intervals; d1++) {
3381
81.9k
              for (int band_num = 0; band_num < max_band; band_num++) {
3382
62.8k
                const int lut_idx_ext = (band_num << 4) + (d0 << 2) + d1;
3383
62.8k
                const int offset_idx = read_ccso_offset_idx(rb);
3384
62.8k
                cm->ccso_info.filter_offset[plane][lut_idx_ext] =
3385
62.8k
                    ccso_offset[offset_idx] *
3386
62.8k
                    ccso_scale[cm->ccso_info.scale_idx[plane]];
3387
62.8k
              }
3388
19.1k
            }
3389
8.88k
          }
3390
5.08k
          av2_copy_ccso_filters(&cm->cur_frame->ccso_info, &cm->ccso_info,
3391
5.08k
                                plane, 1, 0, 0);
3392
5.08k
          cm->cur_frame->ccso_info.ccso_enable[plane] = 1;
3393
3394
5.08k
        } else {  // frame level ccso reuse is true
3395
0
          av2_copy_ccso_filters(&cm->cur_frame->ccso_info, ref_frame_ccso_info,
3396
0
                                plane, 1, 0, 0);
3397
0
          av2_copy_ccso_filters(&cm->ccso_info, ref_frame_ccso_info, plane, 1,
3398
0
                                0, 0);
3399
0
        }
3400
19.3k
      } else {  // disable ccso
3401
19.3k
        cm->cur_frame->ccso_info.ccso_enable[plane] = 0;
3402
19.3k
      }
3403
24.4k
    }
3404
8.68k
  } else {
3405
1
    cm->cur_frame->ccso_info.ccso_enable[0] = 0;
3406
1
    cm->cur_frame->ccso_info.ccso_enable[1] = 0;
3407
1
    cm->cur_frame->ccso_info.ccso_enable[2] = 0;
3408
1
    cm->ccso_info.ccso_enable[0] = 0;
3409
1
    cm->ccso_info.ccso_enable[1] = 0;
3410
1
    cm->ccso_info.ccso_enable[2] = 0;
3411
1
  }
3412
8.68k
}
3413
3414
29.8k
static INLINE int read_delta_q(struct avm_read_bit_buffer *rb) {
3415
29.8k
  return avm_rb_read_bit(rb) ? avm_rb_read_inv_signed_literal(rb, 6) : 0;
3416
29.8k
}
3417
3418
static AVM_INLINE void setup_quantization(CommonQuantParams *quant_params,
3419
                                          int num_planes,
3420
                                          const SequenceHeader *seq_params,
3421
16.3k
                                          struct avm_read_bit_buffer *rb) {
3422
16.3k
  avm_bit_depth_t bit_depth = seq_params->bit_depth;
3423
16.3k
  bool separate_uv_delta_q = seq_params->separate_uv_delta_q;
3424
16.3k
  quant_params->base_qindex = avm_rb_read_literal(
3425
16.3k
      rb, bit_depth == AVM_BITS_8 ? QINDEX_BITS_UNEXT : QINDEX_BITS);
3426
16.3k
  if (seq_params->y_dc_delta_q_enabled)
3427
142
    quant_params->y_dc_delta_q = read_delta_q(rb);
3428
16.2k
  else
3429
16.2k
    quant_params->y_dc_delta_q = 0;
3430
16.3k
  if (num_planes > 1 && (seq_params->uv_dc_delta_q_enabled ||
3431
15.5k
                         seq_params->uv_ac_delta_q_enabled)) {
3432
15.2k
    int diff_uv_delta = 0;
3433
15.2k
    if (separate_uv_delta_q) diff_uv_delta = avm_rb_read_bit(rb);
3434
15.2k
    if (!seq_params->equal_ac_dc_q) {
3435
292
      if (seq_params->uv_dc_delta_q_enabled)
3436
142
        quant_params->u_dc_delta_q = read_delta_q(rb);
3437
150
      else
3438
150
        quant_params->u_dc_delta_q = 0;
3439
292
    }
3440
15.2k
    if (seq_params->uv_ac_delta_q_enabled)
3441
15.2k
      quant_params->u_ac_delta_q = read_delta_q(rb);
3442
0
    else
3443
0
      quant_params->u_ac_delta_q = 0;
3444
15.2k
    if (seq_params->equal_ac_dc_q)
3445
14.9k
      quant_params->u_dc_delta_q = quant_params->u_ac_delta_q;
3446
15.2k
    if (diff_uv_delta) {
3447
14.1k
      if (!seq_params->equal_ac_dc_q) {
3448
115
        if (seq_params->uv_dc_delta_q_enabled)
3449
115
          quant_params->v_dc_delta_q = read_delta_q(rb);
3450
0
        else
3451
0
          quant_params->v_dc_delta_q = 0;
3452
115
      }
3453
14.1k
      if (seq_params->uv_ac_delta_q_enabled)
3454
14.1k
        quant_params->v_ac_delta_q = read_delta_q(rb);
3455
0
      else
3456
0
        quant_params->v_ac_delta_q = 0;
3457
14.1k
      if (seq_params->equal_ac_dc_q)
3458
14.0k
        quant_params->v_dc_delta_q = quant_params->v_ac_delta_q;
3459
14.1k
    } else {
3460
1.13k
      quant_params->v_dc_delta_q = quant_params->u_dc_delta_q;
3461
1.13k
      quant_params->v_ac_delta_q = quant_params->u_ac_delta_q;
3462
1.13k
    }
3463
15.2k
  } else {
3464
1.09k
    quant_params->u_dc_delta_q = 0;
3465
1.09k
    quant_params->u_ac_delta_q = 0;
3466
1.09k
    quant_params->v_dc_delta_q = 0;
3467
1.09k
    quant_params->v_ac_delta_q = 0;
3468
1.09k
  }
3469
16.3k
}
3470
void setup_quant_matrices(AV2Decoder *pbi, CommonQuantParams *quant_params,
3471
23.5k
                          int plane, int qmlevel) {
3472
23.5k
  AV2_COMMON *const cm = &pbi->common;
3473
23.5k
  if (qmlevel >= NUM_QM_LEVELS) {
3474
0
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
3475
0
                       "qmlevel %d is out of boundary", qmlevel);
3476
0
  }
3477
23.5k
  if (qmlevel == NUM_QM_LEVELS - 1) {
3478
12.6k
    for (int t = 0; t < TX_SIZES_ALL; ++t) {
3479
12.1k
      quant_params->giqmatrix[qmlevel][plane][t] = NULL;
3480
12.1k
    }
3481
485
    return;
3482
485
  }
3483
3484
23.0k
  int qm_pos_found = -1;
3485
96.9k
  for (int qm_pos = 0; qm_pos < NUM_CUSTOM_QMS; qm_pos++) {
3486
96.9k
    if (pbi->qm_list[qm_pos].qm_id == qmlevel) {
3487
23.0k
      qm_pos_found = qm_pos;
3488
23.0k
      break;
3489
23.0k
    }
3490
96.9k
  }
3491
23.0k
  if (qm_pos_found < 0) {
3492
1
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
3493
1
                       "quantiztion matrix with Id[%d] is not found", qmlevel);
3494
1
  }
3495
23.0k
  const struct quantization_matrix_set *qmset = &pbi->qm_list[qm_pos_found];
3496
3497
23.0k
  if (qmset->quantizer_matrix_num_planes != av2_num_planes(cm)) {
3498
70
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
3499
70
                       "the quantization matrix and sequence header indicate "
3500
70
                       "different numbers of planes: (%d, %d)",
3501
70
                       qmset->quantizer_matrix_num_planes, av2_num_planes(cm));
3502
70
  }
3503
3504
  //  when a picture indicated in an embedded layer with id equal obu_mlayer_id
3505
  //  and in a temporal layer with id obu_tlayer_id is associated with either
3506
  //  the sequence header or an embedded and temporal layer with ids qmMlayerId
3507
  //  and qmTlayerId, respectively for which
3508
  //  mlayer_dependency_map[obu_mlayer_id][qmMlayerId] and
3509
  //  tlayer_dependency_map[obu_mlayer_id][obu_tlayer_id][qmTlayerId] are both
3510
  //  equal to 1.
3511
23.0k
  if ((qmset->qm_tlayer_id != -1 &&
3512
105
       cm->seq_params.tlayer_dependency_map[cm->mlayer_id][cm->tlayer_id]
3513
105
                                           [qmset->qm_tlayer_id] != 1) ||
3514
22.9k
      (qmset->qm_mlayer_id != -1 &&
3515
78
       cm->seq_params.mlayer_dependency_map[cm->mlayer_id]
3516
78
                                           [qmset->qm_mlayer_id] != 1)) {
3517
27
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
3518
27
                       "the layer ids of the quantization matrices are out"
3519
27
                       "of the limit: (%d, %d)",
3520
27
                       qmset->qm_tlayer_id, qmset->qm_mlayer_id);
3521
27
  }
3522
3523
  // Generate matrices for each tx size
3524
23.0k
  int current = 0;
3525
23.0k
  const bool is_user_defined_qm = qmset->is_user_defined_qm;
3526
597k
  for (int t = 0; t < TX_SIZES_ALL; ++t) {
3527
574k
    const int size = tx_size_2d[t];
3528
574k
    const int qm_tx_size = av2_get_adjusted_tx_size(t);
3529
574k
    if (t != qm_tx_size) {  // Reuse matrices for 'qm_tx_size'
3530
206k
      assert(t > qm_tx_size);
3531
206k
      quant_params->giqmatrix[qmlevel][plane][t] =
3532
206k
          quant_params->giqmatrix[qmlevel][plane][qm_tx_size];
3533
367k
    } else if (is_user_defined_qm &&
3534
1.24k
               (t <= TX_8X8 || t == TX_4X8 || t == TX_8X4)) {
3535
312
      assert(current + size <= QM_TOTAL_SIZE);
3536
      // Generate the iwt matrices from the base matrices.
3537
312
      scale_tx(t, plane, &quant_params->iwt_matrix_ref[qmlevel][plane][current],
3538
312
               qmset->quantizer_matrix);
3539
312
      quant_params->giqmatrix[qmlevel][plane][t] =
3540
312
          &quant_params->iwt_matrix_ref[qmlevel][plane][current];
3541
312
      current += size;
3542
367k
    } else {
3543
      // Fill with reference matrices.
3544
367k
      assert(current + size <= QM_TOTAL_SIZE);
3545
367k
      quant_params->giqmatrix[qmlevel][plane][t] =
3546
367k
          &predefined_iwt_matrix_ref[qmlevel][plane >= 1][current];
3547
367k
      current += size;
3548
367k
    }
3549
574k
  }
3550
23.0k
}
3551
3552
static AVM_INLINE void setup_qm_params(AV2Decoder *pbi,
3553
                                       CommonQuantParams *quant_params,
3554
                                       bool segmentation_enabled,
3555
                                       int num_planes,
3556
16.3k
                                       struct avm_read_bit_buffer *rb) {
3557
16.3k
  quant_params->using_qmatrix = avm_rb_read_bit(rb);
3558
16.3k
  AV2_COMMON *const cm = &pbi->common;
3559
16.3k
  const SequenceHeader *const seq_params = &cm->seq_params;
3560
16.3k
  if (quant_params->using_qmatrix) {
3561
7.16k
    if (segmentation_enabled) {
3562
1.32k
      quant_params->pic_qm_num = avm_rb_read_literal(rb, 2) + 1;
3563
5.84k
    } else {
3564
5.84k
      quant_params->pic_qm_num = 1;
3565
5.84k
    }
3566
#if CONFIG_QM_DEBUG
3567
    printf("[DEC-FRM] pic_qm_num: %d\n", quant_params->pic_qm_num);
3568
#endif
3569
7.16k
    quant_params->qm_index_bits = avm_ceil_log2(quant_params->pic_qm_num);
3570
15.4k
    for (uint8_t i = 0; i < quant_params->pic_qm_num; i++) {
3571
8.26k
      quant_params->qm_y[i] = avm_rb_read_literal(rb, QM_LEVEL_BITS);
3572
8.26k
      if (num_planes > 1) {
3573
7.75k
        const bool qm_uv_same_as_y = avm_rb_read_bit(rb);
3574
#if CONFIG_QM_DEBUG
3575
        printf("[DEC-FRM] qm_uv_same_as_y: %d\n", qm_uv_same_as_y);
3576
#endif
3577
7.75k
        if (qm_uv_same_as_y) {
3578
6.57k
          quant_params->qm_u[i] = quant_params->qm_y[i];
3579
6.57k
          quant_params->qm_v[i] = quant_params->qm_y[i];
3580
6.57k
        } else {
3581
1.18k
          quant_params->qm_u[i] = avm_rb_read_literal(rb, QM_LEVEL_BITS);
3582
1.18k
          if (!seq_params->separate_uv_delta_q) {
3583
74
            quant_params->qm_v[i] = quant_params->qm_u[i];
3584
1.11k
          } else {
3585
1.11k
            quant_params->qm_v[i] = avm_rb_read_literal(rb, QM_LEVEL_BITS);
3586
1.11k
          }
3587
1.18k
        }
3588
7.75k
      }
3589
#if CONFIG_QM_DEBUG
3590
      if (num_planes > 1) {
3591
        printf("[DEC-FRM] qm_y/u/v[%d]: (%d,%d,%d)\n", i, quant_params->qm_y[i],
3592
               quant_params->qm_u[i], quant_params->qm_v[i]);
3593
      } else {
3594
        printf("[DEC-FRM] qm_y[%d]: (%d)\n", i, quant_params->qm_y[i]);
3595
      }
3596
#endif
3597
8.26k
    }
3598
15.4k
    for (uint8_t i = 0; i < quant_params->pic_qm_num; i++) {
3599
8.25k
      setup_quant_matrices(pbi, quant_params, 0, quant_params->qm_y[i]);
3600
8.25k
      if (num_planes > 1) {
3601
7.65k
        setup_quant_matrices(pbi, quant_params, 1, quant_params->qm_u[i]);
3602
7.65k
        setup_quant_matrices(pbi, quant_params, 2, quant_params->qm_v[i]);
3603
7.65k
      }
3604
8.25k
    }
3605
9.20k
  } else {
3606
46.0k
    for (uint8_t i = 0; i < 4; i++) {
3607
36.8k
      quant_params->qm_y[i] = 0;
3608
36.8k
      quant_params->qm_u[i] = 0;
3609
36.8k
      quant_params->qm_v[i] = 0;
3610
36.8k
    }
3611
9.20k
  }
3612
16.3k
}
3613
// Build y/uv dequant values based on segmentation.
3614
static AVM_INLINE void setup_segmentation_dequant(AV2Decoder *const pbi,
3615
16.1k
                                                  MACROBLOCKD *const xd) {
3616
16.1k
  AV2_COMMON *const cm = &pbi->common;
3617
16.1k
  const int bit_depth = cm->seq_params.bit_depth;
3618
  // When segmentation is disabled, only the first value is used.  The
3619
  // remaining are don't cares.
3620
16.1k
  const int max_segments =
3621
16.1k
      cm->seg.enabled ? (cm->seg.enable_ext_seg ? MAX_SEGMENTS : MAX_SEGMENTS_8)
3622
16.1k
                      : 1;
3623
16.1k
  CommonQuantParams *const quant_params = &cm->quant_params;
3624
91.8k
  for (int i = 0; i < max_segments; ++i) {
3625
75.7k
    const int qindex = xd->qindex[i];
3626
75.7k
    quant_params->y_dequant_QTX[i][0] =
3627
75.7k
        av2_dc_quant_QTX(qindex, quant_params->y_dc_delta_q,
3628
75.7k
                         cm->seq_params.base_y_dc_delta_q, bit_depth);
3629
75.7k
    quant_params->y_dequant_QTX[i][1] =
3630
75.7k
        av2_ac_quant_QTX(qindex, 0, 0, bit_depth);
3631
75.7k
    quant_params->u_dequant_QTX[i][0] =
3632
75.7k
        av2_dc_quant_QTX(qindex, quant_params->u_dc_delta_q,
3633
75.7k
                         cm->seq_params.base_uv_dc_delta_q, bit_depth);
3634
75.7k
    quant_params->u_dequant_QTX[i][1] =
3635
75.7k
        av2_ac_quant_QTX(qindex, quant_params->u_ac_delta_q,
3636
75.7k
                         cm->seq_params.base_uv_ac_delta_q, bit_depth);
3637
75.7k
    quant_params->v_dequant_QTX[i][0] =
3638
75.7k
        av2_dc_quant_QTX(qindex, quant_params->v_dc_delta_q,
3639
75.7k
                         cm->seq_params.base_uv_dc_delta_q, bit_depth);
3640
75.7k
    quant_params->v_dequant_QTX[i][1] =
3641
75.7k
        av2_ac_quant_QTX(qindex, quant_params->v_ac_delta_q,
3642
75.7k
                         cm->seq_params.base_uv_ac_delta_q, bit_depth);
3643
75.7k
    const int use_qmatrix = av2_use_qmatrix(quant_params, xd, i);
3644
    // NB: depends on base index so there is only 1 set per frame
3645
    // No quant weighting when lossless or signalled not using QM
3646
75.7k
    const int qm_index = quant_params->qm_index[i];
3647
75.7k
    const int qmlevel_y =
3648
75.7k
        use_qmatrix ? quant_params->qm_y[qm_index] : NUM_QM_LEVELS - 1;
3649
75.7k
    const int qmlevel_y0 =
3650
75.7k
        use_qmatrix ? quant_params->qm_y[0] : NUM_QM_LEVELS - 1;
3651
3652
1.96M
    for (int j = 0; j < TX_SIZES_ALL; ++j) {
3653
1.89M
      if (j > TX_8X8 && j != TX_4X8 && j != TX_8X4)
3654
1.59M
        quant_params->y_iqmatrix[i][j] =
3655
1.59M
            av2_iqmatrix(quant_params, qmlevel_y0, AVM_PLANE_Y, j);
3656
302k
      else
3657
302k
        quant_params->y_iqmatrix[i][j] =
3658
302k
            av2_iqmatrix(quant_params, qmlevel_y, AVM_PLANE_Y, j);
3659
1.89M
    }
3660
75.7k
    const int num_planes = av2_num_planes(cm);
3661
75.7k
    if (num_planes > 1) {
3662
71.5k
      const int qmlevel_u =
3663
71.5k
          use_qmatrix ? quant_params->qm_u[qm_index] : NUM_QM_LEVELS - 1;
3664
71.5k
      const int qmlevel_u0 =
3665
71.5k
          use_qmatrix ? quant_params->qm_u[0] : NUM_QM_LEVELS - 1;
3666
1.86M
      for (int j = 0; j < TX_SIZES_ALL; ++j) {
3667
1.78M
        if (j > TX_8X8 && j != TX_4X8 && j != TX_8X4)
3668
1.50M
          quant_params->u_iqmatrix[i][j] =
3669
1.50M
              av2_iqmatrix(quant_params, qmlevel_u0, AVM_PLANE_U, j);
3670
286k
        else
3671
286k
          quant_params->u_iqmatrix[i][j] =
3672
286k
              av2_iqmatrix(quant_params, qmlevel_u, AVM_PLANE_U, j);
3673
1.78M
      }
3674
71.5k
      const int qmlevel_v =
3675
71.5k
          use_qmatrix ? quant_params->qm_v[qm_index] : NUM_QM_LEVELS - 1;
3676
71.5k
      const int qmlevel_v0 =
3677
71.5k
          use_qmatrix ? quant_params->qm_v[0] : NUM_QM_LEVELS - 1;
3678
1.86M
      for (int j = 0; j < TX_SIZES_ALL; ++j) {
3679
1.78M
        if (j > TX_8X8 && j != TX_4X8 && j != TX_8X4)
3680
1.50M
          quant_params->v_iqmatrix[i][j] =
3681
1.50M
              av2_iqmatrix(quant_params, qmlevel_v0, AVM_PLANE_V, j);
3682
286k
        else
3683
286k
          quant_params->v_iqmatrix[i][j] =
3684
286k
              av2_iqmatrix(quant_params, qmlevel_v, AVM_PLANE_V, j);
3685
1.78M
      }
3686
#if CONFIG_QM_DEBUG
3687
      printf("[DEC-FRM] qmlevel_y/u/v[%d]: (%d,%d,%d)\n", i, qmlevel_y,
3688
             qmlevel_u, qmlevel_v);
3689
#endif
3690
71.5k
    } else {
3691
#if CONFIG_QM_DEBUG
3692
      printf("[DEC-FRM] qmlevel_y[%d]: (%d)\n", i, qmlevel_y);
3693
#endif
3694
4.19k
    }
3695
75.7k
  }
3696
16.1k
}
3697
3698
0
static InterpFilter read_frame_interp_filter(struct avm_read_bit_buffer *rb) {
3699
0
  return avm_rb_read_bit(rb) ? SWITCHABLE
3700
0
                             : avm_rb_read_literal(rb, LOG_SWITCHABLE_FILTERS);
3701
0
}
3702
3703
static AVM_INLINE void setup_render_size(AV2_COMMON *cm,
3704
16.3k
                                         struct avm_read_bit_buffer *rb) {
3705
16.3k
  if (cm->bridge_frame_info.is_bridge_frame) {
3706
0
    return;
3707
0
  }
3708
3709
16.3k
  (void)rb;
3710
16.3k
  if (cm->lcr != NULL && cm->lcr->valid) {
3711
0
    struct LCRXLayerInfo *xlayer_info = NULL;
3712
0
    if (cm->lcr->is_global) {
3713
      // For global LCR find the lxayer inf for the current xlayer_id
3714
0
      struct GlobalLayerConfigurationRecord *global_lcr = &cm->lcr->global_lcr;
3715
0
      for (int i = 0; i < global_lcr->LcrMaxNumXLayerCount; i++) {
3716
0
        if (global_lcr->LcrXLayerID[i] == cm->xlayer_id) {
3717
0
          xlayer_info = &global_lcr->xlayer_info[i];
3718
0
          break;
3719
0
        }
3720
0
      }
3721
0
    } else {
3722
      // for local lcr
3723
0
      xlayer_info = &cm->lcr->local_lcr.xlayer_info;
3724
0
    }
3725
0
    if (xlayer_info != NULL && xlayer_info->lcr_rep_info_present_flag) {
3726
0
      cm->render_width = xlayer_info->rep_params.lcr_max_pic_width;
3727
0
      cm->render_height = xlayer_info->rep_params.lcr_max_pic_height;
3728
0
    } else {
3729
0
      cm->render_width = cm->width;
3730
0
      cm->render_height = cm->height;
3731
0
    }
3732
16.3k
  } else {
3733
    // No active LCR, use the frame dimensions
3734
16.3k
    cm->render_width = cm->width;
3735
16.3k
    cm->render_height = cm->height;
3736
16.3k
  }
3737
16.3k
}
3738
3739
static AVM_INLINE void resize_context_buffers(AV2_COMMON *cm, int width,
3740
16.4k
                                              int height) {
3741
16.4k
#if CONFIG_SIZE_LIMIT
3742
16.4k
  if (width > DECODE_WIDTH_LIMIT || height > DECODE_HEIGHT_LIMIT)
3743
49
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
3744
49
                       "Dimensions of %dx%d beyond allowed size of %dx%d.",
3745
49
                       width, height, DECODE_WIDTH_LIMIT, DECODE_HEIGHT_LIMIT);
3746
16.4k
#endif
3747
16.4k
  if (cm->width != width || cm->height != height) {
3748
2.39k
    const int new_mi_rows =
3749
2.39k
        ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2) >> MI_SIZE_LOG2;
3750
2.39k
    const int new_mi_cols =
3751
2.39k
        ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2) >> MI_SIZE_LOG2;
3752
3753
    // Allocations in av2_alloc_context_buffers() depend on individual
3754
    // dimensions as well as the overall size.
3755
2.39k
    if (new_mi_cols > cm->mi_params.mi_cols ||
3756
2.26k
        new_mi_rows > cm->mi_params.mi_rows) {
3757
2.26k
      if (av2_alloc_context_buffers(cm, width, height)) {
3758
        // The cm->mi_* values have been cleared and any existing context
3759
        // buffers have been freed. Clear cm->width and cm->height to be
3760
        // consistent and to force a realloc next time.
3761
0
        cm->width = 0;
3762
0
        cm->height = 0;
3763
0
        avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
3764
0
                           "Failed to allocate context buffers");
3765
0
      }
3766
2.26k
    } else {
3767
127
      cm->mi_params.set_mb_mi(&cm->mi_params, width, height);
3768
127
    }
3769
2.39k
    av2_init_mi_buffers(&cm->mi_params);
3770
2.39k
    cm->width = width;
3771
2.39k
    cm->height = height;
3772
2.39k
  }
3773
3774
  // We also need to handle the case when `sb_rows` / `sb_cols` has
3775
  // increased due to a change in superblock size. Note that total number of
3776
  // superblocks can *increase* even if frame size has decreased, if
3777
  // superblock size is reduced.
3778
  // We call this function unconditionally, because it already has the logic
3779
  // to reallocte only when necessary.
3780
16.4k
  if (av2_alloc_superblock_info_buffers(cm)) {
3781
0
    avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
3782
0
                       "Failed to allocate superblock info buffers");
3783
0
  }
3784
3785
16.4k
  ensure_mv_buffer(cm->cur_frame, cm);
3786
16.4k
  cm->cur_frame->width = cm->width;
3787
16.4k
  cm->cur_frame->height = cm->height;
3788
16.4k
}
3789
3790
1
static AVM_INLINE void setup_tip_frame_size(AV2_COMMON *cm) {
3791
1
  const SequenceHeader *const seq_params = &cm->seq_params;
3792
1
  const ContentInterpretation *const ci_params =
3793
1
      &cm->ci_params_per_layer[cm->mlayer_id];
3794
1
  const ColorInfo *const color_info = &ci_params->color_info;
3795
1
  YV12_BUFFER_CONFIG *tip_frame_buf = &cm->tip_ref.tip_frame->buf;
3796
1
  if (avm_realloc_frame_buffer(
3797
1
          tip_frame_buf, cm->width, cm->height, seq_params->subsampling_x,
3798
1
          seq_params->subsampling_y, AVM_DEC_BORDER_IN_PIXELS,
3799
1
          cm->features.byte_alignment, NULL, NULL, NULL, false)) {
3800
0
    avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
3801
0
                       "Failed to allocate frame buffer");
3802
0
  }
3803
3804
1
  if (tip_frame_buf) {
3805
1
    tip_frame_buf->bit_depth = (unsigned int)seq_params->bit_depth;
3806
1
    tip_frame_buf->color_primaries = color_info->color_primaries;
3807
1
    tip_frame_buf->transfer_characteristics =
3808
1
        color_info->transfer_characteristics;
3809
1
    tip_frame_buf->matrix_coefficients = color_info->matrix_coefficients;
3810
1
    tip_frame_buf->monochrome = seq_params->monochrome;
3811
1
    if (ci_params->ci_chroma_sample_position_present_flag)
3812
0
      tip_frame_buf->chroma_sample_position =
3813
0
          ci_params->ci_chroma_sample_position[0];
3814
1
    else
3815
1
      tip_frame_buf->chroma_sample_position = AVM_CSP_UNSPECIFIED;
3816
1
    tip_frame_buf->color_range = color_info->full_range_flag;
3817
1
    tip_frame_buf->render_width = cm->render_width;
3818
1
    tip_frame_buf->render_height = cm->render_height;
3819
1
  }
3820
3821
1
  tip_frame_buf = &cm->tip_ref.tmp_tip_frame->buf;
3822
1
  if (avm_realloc_frame_buffer(
3823
1
          tip_frame_buf, cm->width, cm->height, seq_params->subsampling_x,
3824
1
          seq_params->subsampling_y, AVM_DEC_BORDER_IN_PIXELS,
3825
1
          cm->features.byte_alignment, NULL, NULL, NULL, false)) {
3826
0
    avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
3827
0
                       "Failed to allocate frame buffer");
3828
0
  }
3829
3830
1
  if (tip_frame_buf) {
3831
1
    tip_frame_buf->bit_depth = (unsigned int)seq_params->bit_depth;
3832
1
    tip_frame_buf->color_primaries = color_info->color_primaries;
3833
1
    tip_frame_buf->transfer_characteristics =
3834
1
        color_info->transfer_characteristics;
3835
1
    tip_frame_buf->matrix_coefficients = color_info->matrix_coefficients;
3836
1
    tip_frame_buf->monochrome = seq_params->monochrome;
3837
1
    if (ci_params->ci_chroma_sample_position_present_flag)
3838
0
      tip_frame_buf->chroma_sample_position =
3839
0
          ci_params->ci_chroma_sample_position[0];
3840
1
    else
3841
1
      tip_frame_buf->chroma_sample_position = AVM_CSP_UNSPECIFIED;
3842
1
    tip_frame_buf->color_range = color_info->full_range_flag;
3843
1
    tip_frame_buf->render_width = cm->render_width;
3844
1
    tip_frame_buf->render_height = cm->render_height;
3845
1
  }
3846
1
}
3847
3848
16.3k
static AVM_INLINE void setup_buffer_pool(AV2_COMMON *cm) {
3849
16.3k
  BufferPool *const pool = cm->buffer_pool;
3850
16.3k
  const SequenceHeader *const seq_params = &cm->seq_params;
3851
16.3k
  const ContentInterpretation *const ci_params =
3852
16.3k
      &cm->ci_params_per_layer[cm->mlayer_id];
3853
16.3k
  const ColorInfo *const color_info = &ci_params->color_info;
3854
3855
16.3k
  lock_buffer_pool(pool);
3856
16.3k
  if (avm_realloc_frame_buffer(
3857
16.3k
          &cm->cur_frame->buf, cm->width, cm->height, seq_params->subsampling_x,
3858
16.3k
          seq_params->subsampling_y, AVM_DEC_BORDER_IN_PIXELS,
3859
16.3k
          cm->features.byte_alignment, &cm->cur_frame->raw_frame_buffer,
3860
16.3k
          pool->get_fb_cb, pool->cb_priv, false)) {
3861
0
    unlock_buffer_pool(pool);
3862
0
    avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
3863
0
                       "Failed to allocate frame buffer");
3864
0
  }
3865
16.3k
  unlock_buffer_pool(pool);
3866
3867
16.3k
  cm->cur_frame->buf.bit_depth = (unsigned int)seq_params->bit_depth;
3868
16.3k
  cm->cur_frame->buf.color_primaries = color_info->color_primaries;
3869
16.3k
  cm->cur_frame->buf.transfer_characteristics =
3870
16.3k
      color_info->transfer_characteristics;
3871
16.3k
  cm->cur_frame->buf.matrix_coefficients = color_info->matrix_coefficients;
3872
16.3k
  cm->cur_frame->buf.monochrome = seq_params->monochrome;
3873
16.3k
  if (ci_params->ci_chroma_sample_position_present_flag)
3874
0
    cm->cur_frame->buf.chroma_sample_position =
3875
0
        ci_params->ci_chroma_sample_position[0];
3876
16.3k
  else
3877
16.3k
    cm->cur_frame->buf.chroma_sample_position = AVM_CSP_UNSPECIFIED;
3878
16.3k
  cm->cur_frame->buf.color_range = color_info->full_range_flag;
3879
16.3k
  cm->cur_frame->buf.render_width = cm->render_width;
3880
16.3k
  cm->cur_frame->buf.render_height = cm->render_height;
3881
16.3k
  if (seq_params->conf.conf_win_enabled_flag) {
3882
103
    cm->cur_frame->buf.w_conf_win_enabled_flag =
3883
103
        seq_params->conf.conf_win_enabled_flag;
3884
103
    cm->cur_frame->buf.w_win_left_offset =
3885
103
        seq_params->conf.conf_win_left_offset;
3886
103
    cm->cur_frame->buf.w_win_right_offset =
3887
103
        seq_params->conf.conf_win_right_offset;
3888
103
    cm->cur_frame->buf.w_win_top_offset = seq_params->conf.conf_win_top_offset;
3889
103
    cm->cur_frame->buf.w_win_bottom_offset =
3890
103
        seq_params->conf.conf_win_bottom_offset;
3891
16.2k
  } else {
3892
16.2k
    cm->cur_frame->buf.w_win_left_offset = 0;
3893
16.2k
    cm->cur_frame->buf.w_win_right_offset = 0;
3894
16.2k
    cm->cur_frame->buf.w_win_top_offset = 0;
3895
16.2k
    cm->cur_frame->buf.w_win_bottom_offset = 0;
3896
16.2k
  }
3897
16.3k
  cm->cur_frame->buf.max_width = seq_params->max_frame_width;
3898
16.3k
  cm->cur_frame->buf.max_height = seq_params->max_frame_height;
3899
16.3k
  if (cm->seq_params.enable_tip) {
3900
1
    setup_tip_frame_size(cm);
3901
1
  }
3902
16.3k
}
3903
3904
void av2_validate_frame_level_conformance(
3905
    const struct SequenceHeader *seq_params, int frame_width, int frame_height,
3906
16.3k
    struct avm_internal_error_info *error_info) {
3907
16.3k
  const struct CropWindow *conf = &seq_params->conf;
3908
16.3k
  if (!conf->conf_win_enabled_flag) return;
3909
3910
103
  const int SubX = seq_params->subsampling_x + 1;
3911
103
  const int SubY = seq_params->subsampling_y + 1;
3912
103
  const int LeftPosX =
3913
103
      (conf->conf_win_left_offset * frame_width) / seq_params->max_frame_width;
3914
3915
103
  const int RightPosX = frame_width - 1 -
3916
103
                        ((conf->conf_win_right_offset * frame_width) /
3917
103
                         seq_params->max_frame_width);
3918
3919
103
  const int TopPosY =
3920
103
      (conf->conf_win_top_offset * frame_height) / seq_params->max_frame_height;
3921
3922
103
  const int BottomPosY = frame_height - 1 -
3923
103
                         ((conf->conf_win_bottom_offset * frame_height) /
3924
103
                          seq_params->max_frame_height);
3925
3926
  // Conformance requirement 1: LeftPosX == SubX * (LeftPosX/Subx)
3927
103
  if (!seq_params->monochrome && SubX > 1 &&
3928
100
      LeftPosX != SubX * (LeftPosX / SubX)) {
3929
0
    avm_internal_error(
3930
0
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
3931
0
        "Conformance window left position %d must be a multiple of SubX=%d",
3932
0
        LeftPosX, SubX);
3933
0
  }
3934
3935
  // Conformance requirement 2: TopPosY == SubY * (TopPosY / SubY)
3936
103
  if (!seq_params->monochrome && SubY > 1 &&
3937
100
      TopPosY != SubY * (TopPosY / SubY)) {
3938
0
    avm_internal_error(
3939
0
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
3940
0
        "Conformance window top position %d must be a multiple of SubY=%d",
3941
0
        TopPosY, SubY);
3942
0
  }
3943
3944
  // Conformance requirement 3: LeftPosX<= RightPosX
3945
103
  if (LeftPosX > RightPosX) {
3946
1
    avm_internal_error(
3947
1
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
3948
1
        "Conformance window left position %d must be <= right position=%d",
3949
1
        LeftPosX, RightPosX);
3950
1
  }
3951
3952
  // Conformance requirement 4: TopPosY <= BottomPosY
3953
103
  if (TopPosY > BottomPosY) {
3954
0
    avm_internal_error(
3955
0
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
3956
0
        "Conformance window top position %d must be <= bottom position=%d",
3957
0
        TopPosY, BottomPosY);
3958
0
  }
3959
103
}
3960
3961
static void check_lcr_frame_size_conformance_dec(AV2_COMMON *cm, int width,
3962
16.4k
                                                 int height) {
3963
16.4k
  int max_w, max_h, layer_id;
3964
16.4k
  if (check_lcr_frame_size_conformance(cm, width, height, &max_w, &max_h,
3965
16.4k
                                       &layer_id)) {
3966
0
    avm_internal_error(
3967
0
        &cm->error, AVM_CODEC_CORRUPT_FRAME,
3968
0
        "Frame dimensions (%dx%d) exceed LCR max expected dimensions (%dx%d) "
3969
0
        "for embedded layer %d",
3970
0
        width, height, max_w, max_h, layer_id);
3971
0
  }
3972
16.4k
}
3973
3974
static AVM_INLINE void setup_frame_size(AV2_COMMON *cm,
3975
                                        int frame_size_override_flag,
3976
16.4k
                                        struct avm_read_bit_buffer *rb) {
3977
16.4k
  const SequenceHeader *const seq_params = &cm->seq_params;
3978
16.4k
  int width, height;
3979
3980
16.4k
  int num_bits_width = seq_params->num_bits_width;
3981
16.4k
  int num_bits_height = seq_params->num_bits_height;
3982
16.4k
  if (cm->bridge_frame_info.is_bridge_frame) {
3983
0
    cm->bridge_frame_info.bridge_frame_max_width =
3984
0
        avm_rb_read_literal(rb, num_bits_width) + 1;
3985
0
    cm->bridge_frame_info.bridge_frame_max_height =
3986
0
        avm_rb_read_literal(rb, num_bits_height) + 1;
3987
0
    const RefCntBuffer *ref_buf = get_ref_frame_buf(
3988
0
        cm, cm->bridge_frame_info.bridge_frame_ref_idx_remapped);
3989
0
    width =
3990
0
        AVMMIN(cm->bridge_frame_info.bridge_frame_max_width, ref_buf->width);
3991
0
    height =
3992
0
        AVMMIN(cm->bridge_frame_info.bridge_frame_max_height, ref_buf->height);
3993
16.4k
  } else {
3994
16.4k
    if (frame_size_override_flag) {
3995
6
      av2_read_frame_size(rb, num_bits_width, num_bits_height, &width, &height);
3996
6
      if (width > seq_params->max_frame_width ||
3997
6
          height > seq_params->max_frame_height) {
3998
6
        avm_internal_error(
3999
6
            &cm->error, AVM_CODEC_CORRUPT_FRAME,
4000
6
            "Frame dimensions are larger than the maximum values");
4001
6
      }
4002
16.4k
    } else {
4003
16.4k
      assert(cm->mfh_valid[cm->cur_mfh_id]);
4004
16.4k
      if (cm->mfh_params[cm->cur_mfh_id].mfh_frame_size_present_flag) {
4005
0
        width = cm->mfh_params[cm->cur_mfh_id].mfh_frame_width;
4006
0
        height = cm->mfh_params[cm->cur_mfh_id].mfh_frame_height;
4007
16.4k
      } else {
4008
16.4k
        width = seq_params->max_frame_width;
4009
16.4k
        height = seq_params->max_frame_height;
4010
16.4k
      }
4011
16.4k
    }
4012
16.4k
  }
4013
4014
16.4k
  if (!cm->bridge_frame_info.is_bridge_frame) {
4015
16.4k
    check_lcr_frame_size_conformance_dec(cm, width, height);
4016
16.4k
  }
4017
4018
16.4k
  resize_context_buffers(cm, width, height);
4019
16.4k
  setup_render_size(cm, rb);
4020
16.4k
  setup_buffer_pool(cm);
4021
16.4k
  realloc_bru_info(cm);
4022
16.4k
  av2_validate_frame_level_conformance(&cm->seq_params, width, height,
4023
16.4k
                                       &cm->error);
4024
16.4k
}
4025
4026
static AVM_INLINE void setup_seq_sb_size(SequenceHeader *seq_params,
4027
21.9k
                                         struct avm_read_bit_buffer *rb) {
4028
21.9k
  static const BLOCK_SIZE sb_sizes[] = { BLOCK_256X256, BLOCK_128X128,
4029
21.9k
                                         BLOCK_64X64 };
4030
21.9k
  int index = 0;
4031
21.9k
  bool bit = avm_rb_read_bit(rb);
4032
21.9k
  if (!bit) {
4033
19.2k
    index++;
4034
19.2k
    bit = avm_rb_read_bit(rb);
4035
19.2k
    if (!bit) {
4036
17.6k
      index++;
4037
17.6k
    }
4038
19.2k
  }
4039
21.9k
  BLOCK_SIZE sb_size = sb_sizes[index];
4040
21.9k
  seq_params->sb_size = sb_size;
4041
21.9k
  seq_params->mib_size = mi_size_wide[sb_size];
4042
21.9k
  seq_params->mib_size_log2 = mi_size_wide_log2[sb_size];
4043
21.9k
}
4044
4045
static INLINE int valid_ref_frame_img_fmt(avm_bit_depth_t ref_bit_depth,
4046
                                          int ref_xss, int ref_yss,
4047
                                          avm_bit_depth_t this_bit_depth,
4048
0
                                          int this_xss, int this_yss) {
4049
0
  return ref_bit_depth == this_bit_depth && ref_xss == this_xss &&
4050
0
         ref_yss == this_yss;
4051
0
}
4052
4053
static AVM_INLINE void setup_frame_size_with_refs(
4054
    AV2_COMMON *cm, const int explicit_ref_frame_map,
4055
0
    struct avm_read_bit_buffer *rb) {
4056
0
  int width, height;
4057
0
  int found = 0;
4058
  // In implicit reference framework, the reference frame mapping up to this
4059
  // point is a preliminary, resolution independent version, in which case
4060
  // num_total_refs_res_indep and remapped_ref_idx_res_indep are used instead.
4061
0
  const int num_refs = explicit_ref_frame_map
4062
0
                           ? cm->ref_frames_info.num_total_refs
4063
0
                           : cm->ref_frames_info.num_total_refs_res_indep;
4064
0
  for (int i = 0; i < num_refs; ++i) {
4065
0
    if (avm_rb_read_bit(rb)) {
4066
0
      const RefCntBuffer *const ref_buf =
4067
0
          explicit_ref_frame_map ? get_ref_frame_buf(cm, i)
4068
0
                                 : get_ref_frame_buf_res_indep(cm, i);
4069
0
      if (ref_buf->is_restricted) {
4070
0
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
4071
0
                           "Invalid condition: restricted reference buffer");
4072
0
      }
4073
      // This will never be NULL in a normal stream, as streams are required to
4074
      // have a shown keyframe before any inter frames, which would refresh all
4075
      // the reference buffers. However, it might be null if we're starting in
4076
      // the middle of a stream, and static analysis will error if we don't do
4077
      // a null check here.
4078
0
      if (ref_buf == NULL) {
4079
0
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
4080
0
                           "Invalid condition: invalid reference buffer");
4081
0
      } else {
4082
0
        const YV12_BUFFER_CONFIG *const buf = &ref_buf->buf;
4083
0
        width = buf->y_crop_width;
4084
0
        height = buf->y_crop_height;
4085
0
        cm->render_width = buf->render_width;
4086
0
        cm->render_height = buf->render_height;
4087
0
        resize_context_buffers(cm, width, height);
4088
0
        found = 1;
4089
0
        break;
4090
0
      }
4091
0
    }
4092
0
  }
4093
4094
0
  const SequenceHeader *const seq_params = &cm->seq_params;
4095
0
  if (!found) {
4096
0
    int num_bits_width = seq_params->num_bits_width;
4097
0
    int num_bits_height = seq_params->num_bits_height;
4098
4099
0
    av2_read_frame_size(rb, num_bits_width, num_bits_height, &width, &height);
4100
0
    resize_context_buffers(cm, width, height);
4101
0
    setup_render_size(cm, rb);
4102
0
  }
4103
4104
0
  if (width <= 0 || height <= 0)
4105
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
4106
0
                       "Invalid frame size");
4107
4108
0
  check_lcr_frame_size_conformance_dec(cm, width, height);
4109
4110
0
  for (int i = 0; i < num_refs; ++i) {
4111
0
    const RefCntBuffer *const ref_frame =
4112
0
        explicit_ref_frame_map ? get_ref_frame_buf(cm, i)
4113
0
                               : get_ref_frame_buf_res_indep(cm, i);
4114
0
    if (!valid_ref_frame_img_fmt(
4115
0
            ref_frame->buf.bit_depth, ref_frame->buf.subsampling_x,
4116
0
            ref_frame->buf.subsampling_y, seq_params->bit_depth,
4117
0
            seq_params->subsampling_x, seq_params->subsampling_y))
4118
0
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
4119
0
                         "Referenced frame has incompatible color format");
4120
0
  }
4121
0
  setup_buffer_pool(cm);
4122
0
  realloc_bru_info(cm);
4123
0
  av2_validate_frame_level_conformance(&cm->seq_params, width, height,
4124
0
                                       &cm->error);
4125
0
}
4126
4127
// Reuses the tile information
4128
static void reuse_tile_params(CommonTileParams *tiles,
4129
13.9k
                              const CommonTileParams *tile_info) {
4130
13.9k
  tiles->uniform_spacing = tile_info->uniform_spacing;
4131
4132
  // Reuse tile columns
4133
13.9k
  if (tiles->uniform_spacing) {
4134
795
    tiles->log2_cols = tile_info->log2_cols;
4135
13.1k
  } else {
4136
39.4k
    for (int i = 0; i <= tile_info->cols; i++) {
4137
26.3k
      tiles->col_start_sb[i] = tile_info->col_start_sb[i];
4138
26.3k
    }
4139
13.1k
    tiles->cols = tile_info->cols;
4140
13.1k
  }
4141
13.9k
  av2_calculate_tile_cols(tiles);
4142
  // Reuse tile rows
4143
13.9k
  if (tiles->uniform_spacing) {
4144
795
    tiles->log2_rows = tile_info->log2_rows;
4145
13.1k
  } else {
4146
39.4k
    for (int i = 0; i <= tile_info->rows; i++) {
4147
26.3k
      tiles->row_start_sb[i] = tile_info->row_start_sb[i];
4148
26.3k
    }
4149
13.1k
    tiles->rows = tile_info->rows;
4150
13.1k
  }
4151
13.9k
  av2_calculate_tile_rows(tiles);
4152
13.9k
}
4153
4154
static void read_tile_params(CommonTileParams *tiles,
4155
20.1k
                             struct avm_read_bit_buffer *rb) {
4156
20.1k
  tiles->uniform_spacing = avm_rb_read_bit(rb);
4157
4158
  // Read tile columns
4159
20.1k
  if (tiles->uniform_spacing) {
4160
5.44k
    tiles->log2_cols = tiles->min_log2_cols;
4161
12.8k
    while (tiles->log2_cols < tiles->max_log2_cols) {
4162
9.45k
      if (!avm_rb_read_bit(rb)) {
4163
2.06k
        break;
4164
2.06k
      }
4165
7.38k
      tiles->log2_cols++;
4166
7.38k
    }
4167
14.7k
  } else {
4168
14.7k
    int i;
4169
14.7k
    int start_sb;
4170
14.7k
    int width_sb = tiles->sb_cols;
4171
31.1k
    for (i = 0, start_sb = 0; width_sb > 0; i++) {
4172
16.3k
      if (i >= MAX_TILE_COLS) {
4173
0
        rb->error_handler(rb->error_handler_data, AVM_CODEC_CORRUPT_FRAME,
4174
0
                          "tileCols cannot be greater than MAX_TILE_COLS");
4175
0
      }
4176
16.3k
      const int size_sb =
4177
16.3k
          1 + rb_read_uniform(rb, AVMMIN(width_sb, tiles->max_width_sb));
4178
16.3k
      tiles->col_start_sb[i] = start_sb;
4179
16.3k
      start_sb += size_sb;
4180
16.3k
      width_sb -= size_sb;
4181
16.3k
    }
4182
14.7k
    assert(width_sb == 0);
4183
14.7k
    assert(start_sb == tiles->sb_cols);
4184
14.7k
    tiles->cols = i;
4185
14.7k
    tiles->col_start_sb[i] = start_sb;
4186
14.7k
  }
4187
20.1k
  av2_calculate_tile_cols(tiles);
4188
4189
  // Read tile rows
4190
20.1k
  if (tiles->uniform_spacing) {
4191
5.44k
    tiles->log2_rows = tiles->min_log2_rows;
4192
11.7k
    while (tiles->log2_rows < tiles->max_log2_rows) {
4193
10.0k
      if (!avm_rb_read_bit(rb)) {
4194
3.81k
        break;
4195
3.81k
      }
4196
6.28k
      tiles->log2_rows++;
4197
6.28k
    }
4198
14.7k
  } else {
4199
14.7k
    int i;
4200
14.7k
    int start_sb;
4201
14.7k
    int height_sb = tiles->sb_rows;
4202
32.1k
    for (i = 0, start_sb = 0; height_sb > 0; i++) {
4203
17.4k
      if (i >= MAX_TILE_ROWS) {
4204
0
        rb->error_handler(rb->error_handler_data, AVM_CODEC_CORRUPT_FRAME,
4205
0
                          "tileRows cannot be greater than MAX_TILE_ROWS");
4206
0
      }
4207
17.4k
      const int size_sb =
4208
17.4k
          1 + rb_read_uniform(rb, AVMMIN(height_sb, tiles->max_height_sb));
4209
17.4k
      tiles->row_start_sb[i] = start_sb;
4210
17.4k
      start_sb += size_sb;
4211
17.4k
      height_sb -= size_sb;
4212
17.4k
    }
4213
14.7k
    assert(height_sb == 0);
4214
14.7k
    assert(start_sb == tiles->sb_rows);
4215
14.7k
    tiles->rows = i;
4216
14.7k
    tiles->row_start_sb[i] = start_sb;
4217
14.7k
  }
4218
20.1k
  av2_calculate_tile_rows(tiles);
4219
20.1k
}
4220
4221
static AVM_INLINE void read_tile_info(AV2Decoder *const pbi,
4222
16.3k
                                      struct avm_read_bit_buffer *const rb) {
4223
16.3k
  AV2_COMMON *const cm = &pbi->common;
4224
16.3k
  if (cm->bridge_frame_info.is_bridge_frame) {
4225
0
    return;
4226
0
  }
4227
16.3k
  av2_get_tile_limits(&cm->tiles, cm->mi_params.mi_rows, cm->mi_params.mi_cols,
4228
16.3k
                      cm->mib_size_log2, cm->seq_params.mib_size_log2,
4229
16.3k
                      cm->seq_params.seq_max_level_idx,
4230
16.3k
                      cm->seq_params.seq_tier);
4231
4232
16.3k
  const TileInfoSyntax *const tile_params = find_effective_tile_params(cm);
4233
16.3k
  int reuse = 0;
4234
16.3k
  if (tile_params &&
4235
15.2k
      is_frame_tile_config_reuse_eligible(tile_params, &cm->tiles)) {
4236
14.6k
    if (tile_params->allow_tile_info_change)
4237
1.53k
      reuse = avm_rb_read_bit(rb);
4238
13.1k
    else
4239
13.1k
      reuse = 1;
4240
14.6k
  }
4241
16.3k
  if (reuse) {
4242
13.9k
    reuse_tile_params(&cm->tiles, &tile_params->tile_info);
4243
13.9k
  } else {
4244
2.42k
    read_tile_params(&cm->tiles, rb);
4245
2.42k
  }
4246
4247
16.3k
  if (cm->bru.enabled) {
4248
0
    const int num_tiles = cm->tiles.rows * cm->tiles.cols;
4249
0
    memset(cm->tiles.tile_active_bitmap, 0, (num_tiles + 7) / 8);
4250
0
    if (num_tiles == 1) {
4251
0
      cm->tiles.tile_active_bitmap[0] = 1;
4252
0
    }
4253
0
  }
4254
16.3k
  pbi->context_update_tile_id = 0;
4255
16.3k
  if (cm->tiles.rows * cm->tiles.cols > 1 &&
4256
2.10k
      cm->features.tip_frame_mode != TIP_FRAME_AS_OUTPUT) {
4257
2.10k
    if (!cm->seq_params.enable_avg_cdf || !cm->seq_params.avg_cdf_type) {
4258
      // tile to use for cdf update
4259
25
      pbi->context_update_tile_id =
4260
25
          avm_rb_read_literal(rb, cm->tiles.log2_rows + cm->tiles.log2_cols);
4261
25
      if (pbi->context_update_tile_id >= cm->tiles.rows * cm->tiles.cols) {
4262
4
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
4263
4
                           "Invalid context_update_tile_id");
4264
4
      }
4265
25
    }
4266
    // tile size magnitude
4267
2.10k
    pbi->tile_size_bytes = avm_rb_read_literal(rb, 2) + 1;
4268
2.10k
  }
4269
16.3k
}
4270
4271
26.6k
static size_t mem_get_varsize(const uint8_t *src, int sz) {
4272
26.6k
  switch (sz) {
4273
26.4k
    case 1: return src[0];
4274
90
    case 2: return mem_get_le16(src);
4275
15
    case 3: return mem_get_le24(src);
4276
83
    case 4: return mem_get_le32(src);
4277
0
    default: assert(0 && "Invalid size"); return -1;
4278
26.6k
  }
4279
26.6k
}
4280
4281
// Reads the next tile returning its size and adjusting '*data' accordingly
4282
// based on 'is_last'.
4283
static AVM_INLINE void get_tile_buffer(
4284
    const uint8_t *const data_end, const int tile_size_bytes, int is_last,
4285
    struct avm_internal_error_info *error_info, const uint8_t **data,
4286
30.2k
    TileBufferDec *const buf) {
4287
30.2k
  size_t size;
4288
4289
30.2k
  if (!is_last) {
4290
26.6k
    if (!read_is_valid(*data, tile_size_bytes, data_end))
4291
0
      avm_internal_error(error_info, AVM_CODEC_CORRUPT_FRAME,
4292
0
                         "Not enough data to read tile size");
4293
4294
26.6k
    size = mem_get_varsize(*data, tile_size_bytes) + AV2_MIN_TILE_SIZE_BYTES;
4295
26.6k
    *data += tile_size_bytes;
4296
4297
26.6k
    if (size > (size_t)(data_end - *data))
4298
108
      avm_internal_error(error_info, AVM_CODEC_CORRUPT_FRAME,
4299
108
                         "Truncated packet or corrupt tile size");
4300
26.6k
  } else {
4301
3.60k
    size = data_end - *data;
4302
3.60k
  }
4303
4304
30.2k
  buf->data = *data;
4305
30.2k
  buf->size = size;
4306
4307
30.2k
  *data += size;
4308
30.2k
}
4309
4310
static AVM_INLINE void get_tile_buffers(
4311
    AV2Decoder *pbi, const uint8_t *data, const uint8_t *data_end,
4312
    TileBufferDec (*const tile_buffers)[MAX_TILE_COLS], int start_tile,
4313
3.71k
    int end_tile) {
4314
3.71k
  AV2_COMMON *const cm = &pbi->common;
4315
3.71k
  int tile_cols = cm->tiles.cols;
4316
3.71k
  int tile_rows = cm->tiles.rows;
4317
3.71k
  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) {
4318
0
    tile_cols = 1;
4319
0
    tile_rows = 1;
4320
0
    end_tile = 0;
4321
0
  }
4322
3.71k
  int tc = 0;
4323
4324
14.2k
  for (int r = 0; r < tile_rows; ++r) {
4325
40.8k
    for (int c = 0; c < tile_cols; ++c, ++tc) {
4326
30.2k
      TileBufferDec *const buf = &tile_buffers[r][c];
4327
4328
30.2k
      const int is_last = (tc == end_tile);
4329
30.2k
      const size_t hdr_offset = 0;
4330
4331
30.2k
      if (tc < start_tile || tc > end_tile) continue;
4332
4333
30.2k
      if (data + hdr_offset >= data_end)
4334
0
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
4335
0
                           "Data ended before all tiles were read.");
4336
30.2k
      data += hdr_offset;
4337
30.2k
      get_tile_buffer(data_end, pbi->tile_size_bytes, is_last,
4338
30.2k
                      &pbi->common.error, &data, buf);
4339
30.2k
      if (cm->bru.enabled) {
4340
0
        const int tile_idx = r * tile_cols + c;
4341
0
        TileDataDec *const this_tile = pbi->tile_data + tile_idx;
4342
0
        const int tile_active_map_byte = tile_idx >> 3;
4343
0
        const int tile_active_map_bit = tile_idx & 7;
4344
0
        this_tile->tile_info.tile_active_mode =
4345
0
            (cm->tiles.tile_active_bitmap[tile_active_map_byte] >>
4346
0
             tile_active_map_bit) &
4347
0
            1;
4348
0
      }
4349
30.2k
    }
4350
10.5k
  }
4351
3.71k
}
4352
4353
static AVM_INLINE void set_cb_buffer(AV2Decoder *pbi, DecoderCodingBlock *dcb,
4354
                                     CB_BUFFER *cb_buffer_base,
4355
                                     const int num_planes, int mi_row,
4356
138k
                                     int mi_col) {
4357
138k
  AV2_COMMON *const cm = &pbi->common;
4358
138k
  int mib_size_log2 = cm->mib_size_log2;
4359
138k
  int stride = (cm->mi_params.mi_cols >> mib_size_log2) + 1;
4360
138k
  int offset = (mi_row >> mib_size_log2) * stride + (mi_col >> mib_size_log2);
4361
138k
  CB_BUFFER *cb_buffer = cb_buffer_base + offset;
4362
4363
552k
  for (int plane = 0; plane < num_planes; ++plane) {
4364
414k
    dcb->dqcoeff_block[plane] = cb_buffer->dqcoeff[plane];
4365
#if CONFIG_INSPECTION
4366
    dcb->dqcoeff_block_copy[plane] = cb_buffer->dqcoeff_copy[plane];
4367
    dcb->qcoeff_block[plane] = cb_buffer->qcoeff[plane];
4368
    dcb->dequant_values[plane] = cb_buffer->dequant_values[plane];
4369
#endif  // CONFIG_INSPECTION
4370
414k
    dcb->eob_data[plane] = cb_buffer->eob_data[plane];
4371
414k
    dcb->bob_data[plane] = cb_buffer->bob_data[plane];
4372
414k
    dcb->cb_offset[plane] = 0;
4373
414k
    dcb->txb_offset[plane] = 0;
4374
414k
  }
4375
138k
  MACROBLOCKD *const xd = &dcb->xd;
4376
138k
  xd->plane[0].color_index_map = cb_buffer->color_index_map[0];
4377
138k
  xd->plane[1].color_index_map = cb_buffer->color_index_map[1];
4378
138k
  xd->color_index_map_offset[0] = 0;
4379
138k
  xd->color_index_map_offset[1] = 0;
4380
138k
}
4381
4382
static AVM_INLINE void decoder_alloc_tile_data(AV2Decoder *pbi,
4383
1.97k
                                               const int n_tiles) {
4384
1.97k
  AV2_COMMON *const cm = &pbi->common;
4385
1.97k
  avm_free(pbi->tile_data);
4386
1.97k
  CHECK_MEM_ERROR(cm, pbi->tile_data,
4387
1.97k
                  avm_memalign(32, n_tiles * sizeof(*pbi->tile_data)));
4388
1.97k
  pbi->allocated_tiles = n_tiles;
4389
30.5k
  for (int i = 0; i < n_tiles; i++) {
4390
28.5k
    TileDataDec *const tile_data = pbi->tile_data + i;
4391
28.5k
    av2_zero(tile_data->dec_row_mt_sync);
4392
28.5k
  }
4393
1.97k
  pbi->allocated_row_mt_sync_rows = 0;
4394
1.97k
}
4395
4396
// Set up nsync by width.
4397
// Note: currently returns a constant value.
4398
// To use alternate nsync numbers picked by testing, see `get_sync_range()` in
4399
// `thread_common.c`.
4400
0
static INLINE int get_sync_range(int width) {
4401
0
  (void)width;
4402
0
  return 1;
4403
0
}
4404
4405
// Allocate memory for decoder row synchronization
4406
static AVM_INLINE void dec_row_mt_alloc(AV2DecRowMTSync *dec_row_mt_sync,
4407
0
                                        AV2_COMMON *cm, int rows) {
4408
0
  dec_row_mt_sync->allocated_sb_rows = rows;
4409
0
#if CONFIG_MULTITHREAD
4410
0
  {
4411
0
    int i;
4412
4413
0
    CHECK_MEM_ERROR(cm, dec_row_mt_sync->mutex_,
4414
0
                    avm_malloc(sizeof(*(dec_row_mt_sync->mutex_)) * rows));
4415
0
    if (dec_row_mt_sync->mutex_) {
4416
0
      for (i = 0; i < rows; ++i) {
4417
0
        pthread_mutex_init(&dec_row_mt_sync->mutex_[i], NULL);
4418
0
      }
4419
0
    }
4420
4421
0
    CHECK_MEM_ERROR(cm, dec_row_mt_sync->cond_,
4422
0
                    avm_malloc(sizeof(*(dec_row_mt_sync->cond_)) * rows));
4423
0
    if (dec_row_mt_sync->cond_) {
4424
0
      for (i = 0; i < rows; ++i) {
4425
0
        pthread_cond_init(&dec_row_mt_sync->cond_[i], NULL);
4426
0
      }
4427
0
    }
4428
0
  }
4429
0
#endif  // CONFIG_MULTITHREAD
4430
4431
0
  CHECK_MEM_ERROR(cm, dec_row_mt_sync->cur_sb_col,
4432
0
                  avm_malloc(sizeof(*(dec_row_mt_sync->cur_sb_col)) * rows));
4433
4434
  // Set up nsync.
4435
0
  dec_row_mt_sync->sync_range = get_sync_range(cm->width);
4436
0
}
4437
4438
// Deallocate decoder row synchronization related mutex and data
4439
27.8k
void av2_dec_row_mt_dealloc(AV2DecRowMTSync *dec_row_mt_sync) {
4440
27.8k
  if (dec_row_mt_sync != NULL) {
4441
27.8k
#if CONFIG_MULTITHREAD
4442
27.8k
    int i;
4443
27.8k
    if (dec_row_mt_sync->mutex_ != NULL) {
4444
0
      for (i = 0; i < dec_row_mt_sync->allocated_sb_rows; ++i) {
4445
0
        pthread_mutex_destroy(&dec_row_mt_sync->mutex_[i]);
4446
0
      }
4447
0
      avm_free(dec_row_mt_sync->mutex_);
4448
0
    }
4449
27.8k
    if (dec_row_mt_sync->cond_ != NULL) {
4450
0
      for (i = 0; i < dec_row_mt_sync->allocated_sb_rows; ++i) {
4451
0
        pthread_cond_destroy(&dec_row_mt_sync->cond_[i]);
4452
0
      }
4453
0
      avm_free(dec_row_mt_sync->cond_);
4454
0
    }
4455
27.8k
#endif  // CONFIG_MULTITHREAD
4456
27.8k
    avm_free(dec_row_mt_sync->cur_sb_col);
4457
4458
    // clear the structure as the source of this call may be a resize in which
4459
    // case this call will be followed by an _alloc() which may fail.
4460
27.8k
    av2_zero(*dec_row_mt_sync);
4461
27.8k
  }
4462
27.8k
}
4463
4464
static INLINE void sync_read(AV2DecRowMTSync *const dec_row_mt_sync, int r,
4465
0
                             int c) {
4466
0
#if CONFIG_MULTITHREAD
4467
0
  const int nsync = dec_row_mt_sync->sync_range;
4468
4469
0
  if (r && !(c & (nsync - 1))) {
4470
0
    pthread_mutex_t *const mutex = &dec_row_mt_sync->mutex_[r - 1];
4471
0
    pthread_mutex_lock(mutex);
4472
4473
0
    while (c > dec_row_mt_sync->cur_sb_col[r - 1] - nsync) {
4474
0
      pthread_cond_wait(&dec_row_mt_sync->cond_[r - 1], mutex);
4475
0
    }
4476
0
    pthread_mutex_unlock(mutex);
4477
0
  }
4478
#else
4479
  (void)dec_row_mt_sync;
4480
  (void)r;
4481
  (void)c;
4482
#endif  // CONFIG_MULTITHREAD
4483
0
}
4484
4485
static INLINE void sync_write(AV2DecRowMTSync *const dec_row_mt_sync, int r,
4486
0
                              int c, const int sb_cols) {
4487
0
#if CONFIG_MULTITHREAD
4488
0
  const int nsync = dec_row_mt_sync->sync_range;
4489
0
  int cur;
4490
0
  int sig = 1;
4491
4492
0
  if (c < sb_cols - 1) {
4493
0
    cur = c;
4494
0
    if (c % nsync) sig = 0;
4495
0
  } else {
4496
0
    cur = sb_cols + nsync;
4497
0
  }
4498
4499
0
  if (sig) {
4500
0
    pthread_mutex_lock(&dec_row_mt_sync->mutex_[r]);
4501
4502
0
    dec_row_mt_sync->cur_sb_col[r] = cur;
4503
4504
0
    pthread_cond_signal(&dec_row_mt_sync->cond_[r]);
4505
0
    pthread_mutex_unlock(&dec_row_mt_sync->mutex_[r]);
4506
0
  }
4507
#else
4508
  (void)dec_row_mt_sync;
4509
  (void)r;
4510
  (void)c;
4511
  (void)sb_cols;
4512
#endif  // CONFIG_MULTITHREAD
4513
0
}
4514
4515
static AVM_INLINE void decode_tile_sb_row(AV2Decoder *pbi, ThreadData *const td,
4516
                                          TileInfo tile_info,
4517
0
                                          const int mi_row) {
4518
0
  AV2_COMMON *const cm = &pbi->common;
4519
0
  const int num_planes = av2_num_planes(cm);
4520
0
  TileDataDec *const tile_data =
4521
0
      pbi->tile_data + tile_info.tile_row * cm->tiles.cols + tile_info.tile_col;
4522
0
  const int sb_cols_in_tile = av2_get_sb_cols_in_tile(cm, tile_info);
4523
0
  const int sb_row_in_tile =
4524
0
      (mi_row - tile_info.mi_row_start) >> cm->mib_size_log2;
4525
0
  int sb_col_in_tile = 0;
4526
4527
0
  av2_zero(td->dcb.xd.ref_mv_bank);
4528
0
  av2_zero(td->dcb.xd.warp_param_bank);
4529
4530
0
  for (int mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
4531
0
       mi_col += cm->mib_size, sb_col_in_tile++) {
4532
0
    av2_reset_is_mi_coded_map(&td->dcb.xd, cm->mib_size);
4533
0
    td->dcb.xd.sbi = av2_get_sb_info(cm, mi_row, mi_col);
4534
0
    set_cb_buffer(pbi, &td->dcb, pbi->cb_buffer_base, num_planes, mi_row,
4535
0
                  mi_col);
4536
4537
0
    sync_read(&tile_data->dec_row_mt_sync, sb_row_in_tile, sb_col_in_tile);
4538
4539
0
    DecoderCodingBlock *const dcb = &td->dcb;
4540
0
    MACROBLOCKD *const xd = &dcb->xd;
4541
4542
0
    av2_reset_refmv_bank(cm, xd, &tile_info, mi_row, mi_col);
4543
4544
    // Decoding of the super-block
4545
0
    decode_partition_sb(pbi, td, mi_row, mi_col, td->bit_reader, cm->sb_size,
4546
0
                        0x2);
4547
4548
0
    sync_write(&tile_data->dec_row_mt_sync, sb_row_in_tile, sb_col_in_tile,
4549
0
               sb_cols_in_tile);
4550
0
  }
4551
0
}
4552
4553
4.44k
static int check_trailing_bits_after_symbol_coder(avm_reader *r) {
4554
4.44k
  if (avm_reader_has_overflowed(r)) return -1;
4555
4556
4.44k
  uint32_t nb_bits = avm_reader_tell(r);
4557
4.44k
  uint32_t nb_bytes = (nb_bits + 7) >> 3;
4558
4.44k
  const uint8_t *p = avm_reader_find_begin(r) + nb_bytes;
4559
4560
  // avm_reader_tell() returns 1 for a newly initialized decoder, and the
4561
  // return value only increases as values are decoded. So nb_bits > 0, and
4562
  // thus p > p_begin. Therefore accessing p[-1] is safe.
4563
4.44k
  uint8_t last_byte = p[-1];
4564
4.44k
  uint8_t pattern = 128 >> ((nb_bits - 1) & 7);
4565
4.44k
  if ((last_byte & (2 * pattern - 1)) != pattern) return -1;
4566
4567
  // Make sure that all padding bytes are zero as required by the spec.
4568
679
  const uint8_t *p_end = avm_reader_find_end(r);
4569
837
  while (p < p_end) {
4570
598
    if (*p != 0) return -1;
4571
158
    p++;
4572
158
  }
4573
239
  return 0;
4574
679
}
4575
4576
static AVM_INLINE void set_decode_func_pointers(ThreadData *td,
4577
29.2k
                                                int parse_decode_flag) {
4578
29.2k
  td->read_coeffs_tx_intra_block_visit = decode_block_void;
4579
29.2k
  td->predict_and_recon_intra_block_visit = decode_block_void;
4580
29.2k
  td->read_coeffs_tx_inter_block_visit = decode_block_void;
4581
29.2k
  td->inverse_tx_inter_block_visit = decode_block_void;
4582
29.2k
  td->inverse_cctx_block_visit = decode_block_void;
4583
29.2k
  td->predict_inter_block_visit = predict_inter_block_void;
4584
29.2k
  td->copy_frame_mvs_block_visit = predict_inter_block_void;
4585
4586
29.2k
  if (parse_decode_flag & 0x1) {
4587
29.2k
    td->read_coeffs_tx_intra_block_visit = read_coeffs_tx_intra_block;
4588
29.2k
    td->read_coeffs_tx_inter_block_visit = av2_read_coeffs_txb_facade;
4589
29.2k
  }
4590
29.2k
  if (parse_decode_flag & 0x2) {
4591
28.8k
    td->predict_and_recon_intra_block_visit =
4592
28.8k
        predict_and_reconstruct_intra_block;
4593
28.8k
    td->inverse_tx_inter_block_visit = inverse_transform_inter_block;
4594
28.8k
    td->inverse_cctx_block_visit = inverse_cross_chroma_transform_block;
4595
28.8k
    td->predict_inter_block_visit = predict_inter_block;
4596
28.8k
    td->copy_frame_mvs_block_visit = copy_frame_mvs_inter_block;
4597
28.8k
  }
4598
29.2k
}
4599
4600
static AVM_INLINE void decode_tile(AV2Decoder *pbi, ThreadData *const td,
4601
29.3k
                                   int tile_row, int tile_col) {
4602
29.3k
  TileInfo tile_info;
4603
4604
29.3k
  AV2_COMMON *const cm = &pbi->common;
4605
29.3k
  const int num_planes = av2_num_planes(cm);
4606
4607
29.3k
  av2_tile_set_row(&tile_info, cm, tile_row);
4608
29.3k
  av2_tile_set_col(&tile_info, cm, tile_col);
4609
29.3k
  DecoderCodingBlock *const dcb = &td->dcb;
4610
29.3k
  MACROBLOCKD *const xd = &dcb->xd;
4611
4612
29.3k
  av2_zero_above_context(cm, xd, tile_info.mi_col_start, tile_info.mi_col_end,
4613
29.3k
                         tile_row);
4614
4615
29.3k
  int num_filter_classes[MAX_MB_PLANE];
4616
114k
  for (int p = 0; p < num_planes; ++p)
4617
84.9k
    num_filter_classes[p] = cm->rst_info[p].num_filter_classes;
4618
29.3k
  av2_reset_loop_restoration(xd, 0, num_planes, num_filter_classes);
4619
29.3k
  if (cm->bru.enabled || cm->bridge_frame_info.is_bridge_frame) {
4620
0
    if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame)
4621
0
      xd->tile.tile_active_mode = 0;
4622
0
  }
4623
4624
116k
  for (int mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end;
4625
105k
       mi_row += cm->mib_size) {
4626
105k
    av2_zero_left_context(xd);
4627
105k
    av2_zero(xd->ref_mv_bank);
4628
4629
105k
    av2_zero(xd->warp_param_bank);
4630
4631
225k
    for (int mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
4632
139k
         mi_col += cm->mib_size) {
4633
139k
      av2_reset_is_mi_coded_map(xd, cm->mib_size);
4634
139k
      BruActiveMode sb_active_mode = BRU_ACTIVE_SB;
4635
139k
      av2_set_sb_info(cm, xd, mi_row, mi_col, sb_active_mode);
4636
139k
      set_cb_buffer(pbi, dcb, &td->cb_buffer_base, num_planes, 0, 0);
4637
      // td->ref_mv_bank is initialized as xd->ref_mv_bank, and used
4638
      // for MV referencing during decoding the tile.
4639
      // xd->ref_mv_bank is updated as decoding goes.
4640
139k
      av2_reset_refmv_bank(cm, xd, &tile_info, mi_row, mi_col);
4641
4642
139k
      decode_partition_sb(pbi, td, mi_row, mi_col, td->bit_reader, cm->sb_size,
4643
139k
                          0x3);
4644
4645
139k
      if (avm_reader_has_overflowed(td->bit_reader)) {
4646
18.6k
        avm_merge_corrupted_flag(&dcb->corrupted, 1);
4647
18.6k
        return;
4648
18.6k
      }
4649
139k
    }
4650
105k
  }
4651
10.7k
  int corrupted =
4652
10.7k
      (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) ? 0
4653
10.7k
      : (check_trailing_bits_after_symbol_coder(td->bit_reader))             ? 1
4654
10.7k
                                                                 : 0;
4655
10.7k
  avm_merge_corrupted_flag(&dcb->corrupted, corrupted);
4656
10.7k
}
4657
4658
#if CONFIG_THROUGHPUT_ANALYSIS
4659
static void avm_accounting_cal_total(AV2Decoder *pbi) {
4660
  if (pbi->decoding_first_frame) {
4661
    pbi->common.sym_stats.frame_dec_order = 0;
4662
    pbi->common.sym_stats.tot_ctx_syms = 0;
4663
    pbi->common.sym_stats.total_total_hits = 0;
4664
    pbi->common.sym_stats.total_context_switch = 0;
4665
    pbi->common.sym_stats.tot_bypass_syms = 0;
4666
    pbi->common.sym_stats.tot_bits = 0;
4667
    pbi->common.sym_stats.peak_ctx_syms = 0;
4668
    pbi->common.sym_stats.peak_bypass_syms = 0;
4669
    pbi->common.sym_stats.peak_bits = 0;
4670
  }
4671
  Accounting accounting = pbi->accounting;
4672
  int64_t frm_ctx_syms = accounting.syms.num_ctx_coded;
4673
  int64_t frm_bypass_syms = accounting.syms.num_bypass_coded;
4674
  int64_t frm_context_switch = accounting.syms.context_switch;
4675
  int64_t frm_total_hits = accounting.syms.total_hits;
4676
  int64_t frm_bits = 0;
4677
  for (int i = 0; i < accounting.syms.num_syms; i++) {
4678
    AccountingSymbol sym = accounting.syms.syms[i];
4679
    frm_bits += sym.bits;
4680
  }
4681
  int64_t peak_ctx_syms = pbi->common.sym_stats.peak_ctx_syms;
4682
  int64_t peak_bypass_syms = pbi->common.sym_stats.peak_bypass_syms;
4683
  pbi->common.sym_stats.tot_ctx_syms += frm_ctx_syms;
4684
  pbi->common.sym_stats.total_context_switch += frm_context_switch;
4685
  pbi->common.sym_stats.total_total_hits += frm_total_hits;
4686
  pbi->common.sym_stats.tot_bypass_syms += frm_bypass_syms;
4687
  pbi->common.sym_stats.frame_dec_order += 1;
4688
  pbi->common.sym_stats.tot_bits += frm_bits;
4689
  if (frm_ctx_syms * 4 + frm_bypass_syms >
4690
      peak_ctx_syms * 4 + peak_bypass_syms) {
4691
    pbi->common.sym_stats.peak_ctx_syms = frm_ctx_syms;
4692
    pbi->common.sym_stats.peak_bypass_syms = frm_bypass_syms;
4693
    pbi->common.sym_stats.peak_bits = frm_bits;
4694
  }
4695
  tot_ctx_syms = pbi->common.sym_stats.tot_ctx_syms;
4696
  tot_bypass_syms = pbi->common.sym_stats.tot_bypass_syms;
4697
  tot_bits = pbi->common.sym_stats.tot_bits;
4698
  total_context_switch = pbi->common.sym_stats.total_context_switch;
4699
  total_total_hits = pbi->common.sym_stats.total_total_hits;
4700
  max_ctx_syms = pbi->common.sym_stats.peak_ctx_syms;
4701
  max_bypass_syms = pbi->common.sym_stats.peak_bypass_syms;
4702
  max_bits = pbi->common.sym_stats.peak_bits;
4703
  tot_frames = pbi->common.sym_stats.frame_dec_order;
4704
}
4705
#endif  // CONFIG_THROUGHPUT_ANALYSIS
4706
4707
static const uint8_t *decode_tiles(AV2Decoder *pbi, const uint8_t *data,
4708
                                   const uint8_t *data_end, int start_tile,
4709
2.14k
                                   int end_tile) {
4710
2.14k
  AV2_COMMON *const cm = &pbi->common;
4711
2.14k
  ThreadData *const td = &pbi->td;
4712
2.14k
  CommonTileParams *const tiles = &cm->tiles;
4713
2.14k
  const int tile_cols = tiles->cols;
4714
2.14k
  const int tile_rows = tiles->rows;
4715
2.14k
  const int n_tiles = tile_cols * tile_rows;
4716
2.14k
  TileBufferDec(*const tile_buffers)[MAX_TILE_COLS] = pbi->tile_buffers;
4717
2.14k
  int tile_rows_start;
4718
2.14k
  int tile_rows_end;
4719
2.14k
  int tile_cols_start;
4720
2.14k
  int tile_cols_end;
4721
2.14k
  int inv_col_order;
4722
2.14k
  int inv_row_order;
4723
2.14k
  int tile_row, tile_col;
4724
2.14k
  uint8_t allow_update_cdf;
4725
4726
2.14k
  tile_rows_start = 0;
4727
2.14k
  tile_rows_end = tile_rows;
4728
2.14k
  tile_cols_start = 0;
4729
2.14k
  tile_cols_end = tile_cols;
4730
2.14k
  inv_col_order = pbi->inv_tile_order;
4731
2.14k
  inv_row_order = pbi->inv_tile_order;
4732
4733
  // No tiles to decode.
4734
2.14k
  if (tile_rows_end <= tile_rows_start || tile_cols_end <= tile_cols_start ||
4735
      // First tile is larger than end_tile.
4736
2.14k
      tile_rows_start * tiles->cols + tile_cols_start > end_tile ||
4737
      // Last tile is smaller than start_tile.
4738
2.14k
      (tile_rows_end - 1) * tiles->cols + tile_cols_end - 1 < start_tile)
4739
0
    return data;
4740
4741
2.14k
  allow_update_cdf = !cm->features.disable_cdf_update;
4742
4743
2.14k
  assert(tile_rows <= MAX_TILE_ROWS);
4744
2.14k
  assert(tile_cols <= MAX_TILE_COLS);
4745
2.14k
  if (pbi->tile_data == NULL || n_tiles != pbi->allocated_tiles) {
4746
1.05k
    decoder_alloc_tile_data(pbi, n_tiles);
4747
1.05k
  }
4748
2.14k
  get_tile_buffers(pbi, data, data_end, tile_buffers, start_tile, end_tile);
4749
#if CONFIG_ACCOUNTING
4750
  if (pbi->acct_enabled) {
4751
    avm_accounting_reset(&pbi->accounting);
4752
  }
4753
#endif
4754
4755
2.14k
  set_decode_func_pointers(&pbi->td, 0x3);
4756
4757
  // Load all tile information into thread_data.
4758
2.14k
  td->dcb = pbi->dcb;
4759
4760
2.14k
  td->dcb.corrupted = 0;
4761
2.14k
  td->dcb.mc_buf[0] = td->mc_buf[0];
4762
2.14k
  td->dcb.mc_buf[1] = td->mc_buf[1];
4763
2.14k
  td->dcb.xd.tmp_conv_dst = td->tmp_conv_dst;
4764
4765
  // Temporary buffers used during the SMVR and OPFL processing.
4766
2.14k
  td->dcb.xd.opfl_vxy_bufs = td->opfl_vxy_bufs;
4767
2.14k
  td->dcb.xd.opfl_gxy_bufs = td->opfl_gxy_bufs;
4768
2.14k
  td->dcb.xd.opfl_dst_bufs = td->opfl_dst_bufs;
4769
4770
4.28k
  for (tile_row = tile_rows_start; tile_row < tile_rows_end; ++tile_row) {
4771
2.14k
    const int row = inv_row_order ? tile_rows - 1 - tile_row : tile_row;
4772
4773
4.28k
    for (tile_col = tile_cols_start; tile_col < tile_cols_end; ++tile_col) {
4774
2.14k
      const int col = inv_col_order ? tile_cols - 1 - tile_col : tile_col;
4775
2.14k
      TileDataDec *const tile_data = pbi->tile_data + row * tiles->cols + col;
4776
2.14k
      const TileBufferDec *const tile_bs_buf = &tile_buffers[row][col];
4777
4778
2.14k
      if (row * tiles->cols + col < start_tile ||
4779
2.14k
          row * tiles->cols + col > end_tile)
4780
0
        continue;
4781
4782
2.14k
      td->bit_reader = &tile_data->bit_reader;
4783
      // av2_zero(td->cb_buffer_base.dqcoeff);
4784
2.14k
      av2_tile_init(&td->dcb.xd.tile, cm, row, col);
4785
2.14k
      td->dcb.xd.current_base_qindex = cm->quant_params.base_qindex;
4786
2.14k
      setup_bool_decoder(tile_bs_buf->data, data_end, tile_bs_buf->size,
4787
2.14k
                         &cm->error, td->bit_reader, allow_update_cdf);
4788
#if CONFIG_ACCOUNTING
4789
      if (pbi->acct_enabled) {
4790
        td->bit_reader->accounting = &pbi->accounting;
4791
        td->bit_reader->accounting->last_tell_frac =
4792
            avm_reader_tell_frac(td->bit_reader);
4793
      } else {
4794
        td->bit_reader->accounting = NULL;
4795
      }
4796
#endif
4797
2.14k
      av2_init_macroblockd(cm, &td->dcb.xd);
4798
2.14k
      av2_init_above_context(&cm->above_contexts, av2_num_planes(cm), row,
4799
2.14k
                             &td->dcb.xd);
4800
4801
2.14k
      td->dcb.xd.tile.tile_active_mode = 1;
4802
2.14k
      if (cm->bru.enabled && (cm->tiles.cols * cm->tiles.rows > 1)) {
4803
0
        td->dcb.xd.tile.tile_active_mode =
4804
0
            tile_data->tile_info.tile_active_mode;
4805
0
      }
4806
      // Initialise the tile context from the frame context
4807
2.14k
      tile_data->tctx = *cm->fc;
4808
2.14k
      td->dcb.xd.tile_ctx = &tile_data->tctx;
4809
4810
      // decode tile
4811
2.14k
      decode_tile(pbi, td, row, col);
4812
2.14k
      avm_merge_corrupted_flag(&pbi->dcb.corrupted, td->dcb.corrupted);
4813
2.14k
      if (pbi->dcb.corrupted)
4814
1.39k
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
4815
1.39k
                           "Failed to decode tile data");
4816
2.14k
    }
4817
2.14k
  }
4818
4819
2.14k
  TileDataDec *const tile_data = pbi->tile_data + end_tile;
4820
#if CONFIG_THROUGHPUT_ANALYSIS
4821
  if (pbi->acct_enabled) {
4822
    avm_accounting_cal_total(pbi);
4823
  }
4824
#endif  // CONFIG_THROUGHPUT_ANALYSIS
4825
2.14k
  return avm_reader_find_end(&tile_data->bit_reader);
4826
2.14k
}
4827
4828
27.3k
static TileJobsDec *get_dec_job_info(AV2DecTileMT *tile_mt_info) {
4829
27.3k
  TileJobsDec *cur_job_info = NULL;
4830
27.3k
#if CONFIG_MULTITHREAD
4831
27.3k
  pthread_mutex_lock(tile_mt_info->job_mutex);
4832
4833
27.3k
  if (tile_mt_info->jobs_dequeued < tile_mt_info->jobs_enqueued) {
4834
27.3k
    cur_job_info = tile_mt_info->job_queue + tile_mt_info->jobs_dequeued;
4835
27.3k
    tile_mt_info->jobs_dequeued++;
4836
27.3k
  }
4837
4838
27.3k
  pthread_mutex_unlock(tile_mt_info->job_mutex);
4839
#else
4840
  (void)tile_mt_info;
4841
#endif
4842
27.3k
  return cur_job_info;
4843
27.3k
}
4844
4845
static AVM_INLINE void tile_worker_hook_init(
4846
    AV2Decoder *const pbi, DecWorkerData *const thread_data,
4847
    const TileBufferDec *const tile_buffer, TileDataDec *const tile_data,
4848
27.3k
    uint8_t allow_update_cdf) {
4849
27.3k
  AV2_COMMON *cm = &pbi->common;
4850
27.3k
  ThreadData *const td = thread_data->td;
4851
27.3k
  int tile_row = tile_data->tile_info.tile_row;
4852
27.3k
  int tile_col = tile_data->tile_info.tile_col;
4853
4854
27.3k
  td->bit_reader = &tile_data->bit_reader;
4855
27.3k
  av2_zero(td->cb_buffer_base.dqcoeff);
4856
4857
27.3k
  MACROBLOCKD *const xd = &td->dcb.xd;
4858
27.3k
  av2_tile_init(&xd->tile, cm, tile_row, tile_col);
4859
27.3k
  xd->current_base_qindex = cm->quant_params.base_qindex;
4860
27.3k
  setup_bool_decoder(tile_buffer->data, thread_data->data_end,
4861
27.3k
                     tile_buffer->size, &thread_data->error_info,
4862
27.3k
                     td->bit_reader, allow_update_cdf);
4863
#if CONFIG_ACCOUNTING
4864
  if (pbi->acct_enabled) {
4865
    td->bit_reader->accounting = &pbi->accounting;
4866
    td->bit_reader->accounting->last_tell_frac =
4867
        avm_reader_tell_frac(td->bit_reader);
4868
  } else {
4869
    td->bit_reader->accounting = NULL;
4870
  }
4871
#endif
4872
27.3k
  av2_init_macroblockd(cm, xd);
4873
27.3k
  xd->error_info = &thread_data->error_info;
4874
27.3k
  av2_init_above_context(&cm->above_contexts, av2_num_planes(cm), tile_row, xd);
4875
27.3k
  td->dcb.xd.tile.tile_active_mode = 1;
4876
27.3k
  if (cm->bru.enabled && (cm->tiles.cols * cm->tiles.rows > 1)) {
4877
0
    td->dcb.xd.tile.tile_active_mode = tile_data->tile_info.tile_active_mode;
4878
0
  }
4879
  // Initialise the tile context from the frame context
4880
27.3k
  tile_data->tctx = *cm->fc;
4881
27.3k
  xd->tile_ctx = &tile_data->tctx;
4882
#if CONFIG_ACCOUNTING
4883
  if (pbi->acct_enabled) {
4884
    tile_data->bit_reader.accounting->last_tell_frac =
4885
        avm_reader_tell_frac(&tile_data->bit_reader);
4886
  }
4887
#endif
4888
27.3k
}
4889
4890
27.3k
static int tile_worker_hook(void *arg1, void *arg2) {
4891
27.3k
  DecWorkerData *const thread_data = (DecWorkerData *)arg1;
4892
27.3k
  AV2Decoder *const pbi = (AV2Decoder *)arg2;
4893
27.3k
  AV2_COMMON *cm = &pbi->common;
4894
27.3k
  ThreadData *const td = thread_data->td;
4895
27.3k
  uint8_t allow_update_cdf;
4896
4897
  // The jmp_buf is valid only for the duration of the function that calls
4898
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
4899
  // before it returns.
4900
27.3k
  if (setjmp(thread_data->error_info.jmp)) {
4901
5.68k
    thread_data->error_info.setjmp = 0;
4902
5.68k
    thread_data->td->dcb.corrupted = 1;
4903
5.68k
    return 0;
4904
5.68k
  }
4905
21.6k
  thread_data->error_info.setjmp = 1;
4906
4907
21.6k
  allow_update_cdf = !cm->features.disable_cdf_update;
4908
4909
21.6k
  set_decode_func_pointers(td, 0x3);
4910
4911
21.6k
  assert(cm->tiles.cols > 0);
4912
48.9k
  while (!td->dcb.corrupted) {
4913
27.3k
    TileJobsDec *cur_job_info = get_dec_job_info(&pbi->tile_mt_info);
4914
4915
27.3k
    if (cur_job_info != NULL) {
4916
27.3k
      const TileBufferDec *const tile_buffer = cur_job_info->tile_buffer;
4917
27.3k
      TileDataDec *const tile_data = cur_job_info->tile_data;
4918
27.3k
      tile_worker_hook_init(pbi, thread_data, tile_buffer, tile_data,
4919
27.3k
                            allow_update_cdf);
4920
      // decode tile
4921
27.3k
      int tile_row = tile_data->tile_info.tile_row;
4922
27.3k
      int tile_col = tile_data->tile_info.tile_col;
4923
27.3k
      decode_tile(pbi, td, tile_row, tile_col);
4924
18.4E
    } else {
4925
18.4E
      break;
4926
18.4E
    }
4927
27.3k
  }
4928
21.6k
  thread_data->error_info.setjmp = 0;
4929
21.6k
  return !td->dcb.corrupted;
4930
27.3k
}
4931
4932
static INLINE int get_max_row_mt_workers_per_tile(AV2_COMMON *cm,
4933
0
                                                  TileInfo tile) {
4934
  // NOTE: Currently value of max workers is calculated based
4935
  // on the parse and decode time. As per the theoretical estimate
4936
  // when percentage of parse time is equal to percentage of decode
4937
  // time, number of workers needed to parse + decode a tile can not
4938
  // exceed more than 2.
4939
  // TODO(any): Modify this value if parsing is optimized in future.
4940
0
  int sb_rows = av2_get_sb_rows_in_tile(cm, tile);
4941
0
  int max_workers =
4942
0
      sb_rows == 1 ? AVM_MIN_THREADS_PER_TILE : AVM_MAX_THREADS_PER_TILE;
4943
0
  return max_workers;
4944
0
}
4945
4946
// The caller must hold pbi->row_mt_mutex_ when calling this function.
4947
// Returns 1 if either the next job is stored in *next_job_info or 1 is stored
4948
// in *end_of_frame.
4949
// NOTE: The caller waits on pbi->row_mt_cond_ if this function returns 0.
4950
// The return value of this function depends on the following variables:
4951
// - frame_row_mt_info->mi_rows_parse_done
4952
// - frame_row_mt_info->mi_rows_decode_started
4953
// - frame_row_mt_info->row_mt_exit
4954
// Therefore we may need to signal or broadcast pbi->row_mt_cond_ if any of
4955
// these variables is modified.
4956
static int get_next_job_info(AV2Decoder *const pbi,
4957
                             AV2DecRowMTJobInfo *next_job_info,
4958
0
                             int *end_of_frame) {
4959
0
  AV2_COMMON *cm = &pbi->common;
4960
0
  TileDataDec *tile_data;
4961
0
  AV2DecRowMTSync *dec_row_mt_sync;
4962
0
  AV2DecRowMTInfo *frame_row_mt_info = &pbi->frame_row_mt_info;
4963
0
  TileInfo tile_info;
4964
0
  const int tile_rows_start = frame_row_mt_info->tile_rows_start;
4965
0
  const int tile_rows_end = frame_row_mt_info->tile_rows_end;
4966
0
  const int tile_cols_start = frame_row_mt_info->tile_cols_start;
4967
0
  const int tile_cols_end = frame_row_mt_info->tile_cols_end;
4968
0
  const int start_tile = frame_row_mt_info->start_tile;
4969
0
  const int end_tile = frame_row_mt_info->end_tile;
4970
0
  const int sb_mi_size = mi_size_wide[cm->sb_size];
4971
0
  int num_mis_to_decode, num_threads_working;
4972
0
  int num_mis_waiting_for_decode;
4973
0
  int min_threads_working = INT_MAX;
4974
0
  int max_mis_to_decode = 0;
4975
0
  int tile_row_idx, tile_col_idx;
4976
0
  int tile_row = -1;
4977
0
  int tile_col = -1;
4978
4979
0
  memset(next_job_info, 0, sizeof(*next_job_info));
4980
4981
  // Frame decode is completed or error is encountered.
4982
0
  *end_of_frame = (frame_row_mt_info->mi_rows_decode_started ==
4983
0
                   frame_row_mt_info->mi_rows_to_decode) ||
4984
0
                  (frame_row_mt_info->row_mt_exit == 1);
4985
0
  if (*end_of_frame) {
4986
0
    return 1;
4987
0
  }
4988
4989
  // Decoding cannot start as bit-stream parsing is not complete.
4990
0
  assert(frame_row_mt_info->mi_rows_parse_done >=
4991
0
         frame_row_mt_info->mi_rows_decode_started);
4992
0
  if (frame_row_mt_info->mi_rows_parse_done ==
4993
0
      frame_row_mt_info->mi_rows_decode_started)
4994
0
    return 0;
4995
4996
  // Choose the tile to decode.
4997
0
  for (tile_row_idx = tile_rows_start; tile_row_idx < tile_rows_end;
4998
0
       ++tile_row_idx) {
4999
0
    for (tile_col_idx = tile_cols_start; tile_col_idx < tile_cols_end;
5000
0
         ++tile_col_idx) {
5001
0
      if (tile_row_idx * cm->tiles.cols + tile_col_idx < start_tile ||
5002
0
          tile_row_idx * cm->tiles.cols + tile_col_idx > end_tile)
5003
0
        continue;
5004
5005
0
      tile_data = pbi->tile_data + tile_row_idx * cm->tiles.cols + tile_col_idx;
5006
0
      dec_row_mt_sync = &tile_data->dec_row_mt_sync;
5007
5008
0
      num_threads_working = dec_row_mt_sync->num_threads_working;
5009
0
      num_mis_waiting_for_decode = (dec_row_mt_sync->mi_rows_parse_done -
5010
0
                                    dec_row_mt_sync->mi_rows_decode_started) *
5011
0
                                   dec_row_mt_sync->mi_cols;
5012
0
      num_mis_to_decode =
5013
0
          (dec_row_mt_sync->mi_rows - dec_row_mt_sync->mi_rows_decode_started) *
5014
0
          dec_row_mt_sync->mi_cols;
5015
5016
0
      assert(num_mis_to_decode >= num_mis_waiting_for_decode);
5017
5018
      // Pick the tile which has minimum number of threads working on it.
5019
0
      if (num_mis_waiting_for_decode > 0) {
5020
0
        if (num_threads_working < min_threads_working) {
5021
0
          min_threads_working = num_threads_working;
5022
0
          max_mis_to_decode = 0;
5023
0
        }
5024
0
        if (num_threads_working == min_threads_working &&
5025
0
            num_mis_to_decode > max_mis_to_decode &&
5026
0
            num_threads_working <
5027
0
                get_max_row_mt_workers_per_tile(cm, tile_data->tile_info)) {
5028
0
          max_mis_to_decode = num_mis_to_decode;
5029
0
          tile_row = tile_row_idx;
5030
0
          tile_col = tile_col_idx;
5031
0
        }
5032
0
      }
5033
0
    }
5034
0
  }
5035
  // No job found to process
5036
0
  if (tile_row == -1 || tile_col == -1) return 0;
5037
5038
0
  tile_data = pbi->tile_data + tile_row * cm->tiles.cols + tile_col;
5039
0
  tile_info = tile_data->tile_info;
5040
0
  dec_row_mt_sync = &tile_data->dec_row_mt_sync;
5041
5042
0
  next_job_info->tile_row = tile_row;
5043
0
  next_job_info->tile_col = tile_col;
5044
0
  next_job_info->mi_row =
5045
0
      dec_row_mt_sync->mi_rows_decode_started + tile_info.mi_row_start;
5046
5047
0
  dec_row_mt_sync->num_threads_working++;
5048
0
  dec_row_mt_sync->mi_rows_decode_started += sb_mi_size;
5049
0
  frame_row_mt_info->mi_rows_decode_started += sb_mi_size;
5050
0
  assert(frame_row_mt_info->mi_rows_parse_done >=
5051
0
         frame_row_mt_info->mi_rows_decode_started);
5052
0
#if CONFIG_MULTITHREAD
5053
0
  if (frame_row_mt_info->mi_rows_decode_started ==
5054
0
      frame_row_mt_info->mi_rows_to_decode) {
5055
0
    pthread_cond_broadcast(pbi->row_mt_cond_);
5056
0
  }
5057
0
#endif
5058
5059
0
  return 1;
5060
0
}
5061
5062
static INLINE void signal_parse_sb_row_done(AV2Decoder *const pbi,
5063
                                            TileDataDec *const tile_data,
5064
0
                                            const int sb_mi_size) {
5065
0
  AV2DecRowMTInfo *frame_row_mt_info = &pbi->frame_row_mt_info;
5066
0
#if CONFIG_MULTITHREAD
5067
0
  pthread_mutex_lock(pbi->row_mt_mutex_);
5068
0
#endif
5069
0
  assert(frame_row_mt_info->mi_rows_parse_done >=
5070
0
         frame_row_mt_info->mi_rows_decode_started);
5071
0
  tile_data->dec_row_mt_sync.mi_rows_parse_done += sb_mi_size;
5072
0
  frame_row_mt_info->mi_rows_parse_done += sb_mi_size;
5073
0
#if CONFIG_MULTITHREAD
5074
  // A new decode job is available. Wake up one worker thread to handle the
5075
  // new decode job.
5076
  // NOTE: This assumes we bump mi_rows_parse_done and mi_rows_decode_started
5077
  // by the same increment (sb_mi_size).
5078
0
  pthread_cond_signal(pbi->row_mt_cond_);
5079
0
  pthread_mutex_unlock(pbi->row_mt_mutex_);
5080
0
#endif
5081
0
}
5082
5083
// This function is very similar to decode_tile(). It would be good to figure
5084
// out how to share code.
5085
static AVM_INLINE void parse_tile_row_mt(AV2Decoder *pbi, ThreadData *const td,
5086
0
                                         TileDataDec *const tile_data) {
5087
0
  AV2_COMMON *const cm = &pbi->common;
5088
0
  const int sb_mi_size = mi_size_wide[cm->sb_size];
5089
0
  const int num_planes = av2_num_planes(cm);
5090
0
  TileInfo tile_info = tile_data->tile_info;
5091
0
  int tile_row = tile_info.tile_row;
5092
0
  DecoderCodingBlock *const dcb = &td->dcb;
5093
0
  MACROBLOCKD *const xd = &dcb->xd;
5094
5095
0
  av2_zero_above_context(cm, xd, tile_info.mi_col_start, tile_info.mi_col_end,
5096
0
                         tile_row);
5097
0
  int num_filter_classes[MAX_MB_PLANE];
5098
0
  for (int p = 0; p < num_planes; ++p)
5099
0
    num_filter_classes[p] = cm->rst_info[p].num_filter_classes;
5100
0
  av2_reset_loop_restoration(xd, 0, num_planes, num_filter_classes);
5101
0
  if (cm->bru.enabled || cm->bridge_frame_info.is_bridge_frame) {
5102
0
    if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame)
5103
0
      xd->tile.tile_active_mode = 0;
5104
0
  }
5105
0
  for (int mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end;
5106
0
       mi_row += cm->mib_size) {
5107
0
    av2_zero_left_context(xd);
5108
0
    av2_zero(xd->ref_mv_bank);
5109
5110
0
    av2_zero(xd->warp_param_bank);
5111
5112
0
    for (int mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
5113
0
         mi_col += cm->mib_size) {
5114
0
      av2_reset_is_mi_coded_map(xd, cm->mib_size);
5115
0
      BruActiveMode sb_active_mode = BRU_ACTIVE_SB;
5116
0
      av2_set_sb_info(cm, xd, mi_row, mi_col, sb_active_mode);
5117
0
      set_cb_buffer(pbi, dcb, pbi->cb_buffer_base, num_planes, mi_row, mi_col);
5118
0
      av2_reset_refmv_bank(cm, xd, &tile_info, mi_row, mi_col);
5119
5120
      // Bit-stream parsing of the superblock
5121
0
      decode_partition_sb(pbi, td, mi_row, mi_col, td->bit_reader, cm->sb_size,
5122
0
                          0x1);
5123
0
      if (avm_reader_has_overflowed(td->bit_reader)) {
5124
0
        avm_merge_corrupted_flag(&dcb->corrupted, 1);
5125
0
        return;
5126
0
      }
5127
0
    }
5128
0
    signal_parse_sb_row_done(pbi, tile_data, sb_mi_size);
5129
0
  }
5130
5131
0
  int corrupted =
5132
0
      (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) ? 0
5133
0
      : (check_trailing_bits_after_symbol_coder(td->bit_reader))             ? 1
5134
0
                                                                 : 0;
5135
0
  avm_merge_corrupted_flag(&dcb->corrupted, corrupted);
5136
0
}
5137
5138
0
static int row_mt_worker_hook(void *arg1, void *arg2) {
5139
0
  DecWorkerData *const thread_data = (DecWorkerData *)arg1;
5140
0
  AV2Decoder *const pbi = (AV2Decoder *)arg2;
5141
0
  AV2_COMMON *cm = &pbi->common;
5142
0
  ThreadData *const td = thread_data->td;
5143
0
  uint8_t allow_update_cdf;
5144
0
  AV2DecRowMTInfo *frame_row_mt_info = &pbi->frame_row_mt_info;
5145
0
  td->dcb.corrupted = 0;
5146
5147
  // The jmp_buf is valid only for the duration of the function that calls
5148
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
5149
  // before it returns.
5150
0
  if (setjmp(thread_data->error_info.jmp)) {
5151
0
    thread_data->error_info.setjmp = 0;
5152
0
    thread_data->td->dcb.corrupted = 1;
5153
0
#if CONFIG_MULTITHREAD
5154
0
    pthread_mutex_lock(pbi->row_mt_mutex_);
5155
0
#endif
5156
0
    frame_row_mt_info->row_mt_exit = 1;
5157
0
#if CONFIG_MULTITHREAD
5158
0
    pthread_cond_broadcast(pbi->row_mt_cond_);
5159
0
    pthread_mutex_unlock(pbi->row_mt_mutex_);
5160
0
#endif
5161
0
    return 0;
5162
0
  }
5163
0
  thread_data->error_info.setjmp = 1;
5164
5165
0
  allow_update_cdf = !cm->features.disable_cdf_update;
5166
5167
0
  set_decode_func_pointers(td, 0x1);
5168
5169
0
  assert(cm->tiles.cols > 0);
5170
0
  while (!td->dcb.corrupted) {
5171
0
    TileJobsDec *cur_job_info = get_dec_job_info(&pbi->tile_mt_info);
5172
5173
0
    if (cur_job_info != NULL) {
5174
0
      const TileBufferDec *const tile_buffer = cur_job_info->tile_buffer;
5175
0
      TileDataDec *const tile_data = cur_job_info->tile_data;
5176
0
      tile_worker_hook_init(pbi, thread_data, tile_buffer, tile_data,
5177
0
                            allow_update_cdf);
5178
0
#if CONFIG_MULTITHREAD
5179
0
      pthread_mutex_lock(pbi->row_mt_mutex_);
5180
0
#endif
5181
0
      tile_data->dec_row_mt_sync.num_threads_working++;
5182
0
#if CONFIG_MULTITHREAD
5183
0
      pthread_mutex_unlock(pbi->row_mt_mutex_);
5184
0
#endif
5185
      // decode tile
5186
0
      parse_tile_row_mt(pbi, td, tile_data);
5187
0
#if CONFIG_MULTITHREAD
5188
0
      pthread_mutex_lock(pbi->row_mt_mutex_);
5189
0
#endif
5190
0
      tile_data->dec_row_mt_sync.num_threads_working--;
5191
0
#if CONFIG_MULTITHREAD
5192
0
      pthread_mutex_unlock(pbi->row_mt_mutex_);
5193
0
#endif
5194
0
    } else {
5195
0
      break;
5196
0
    }
5197
0
  }
5198
5199
0
  if (td->dcb.corrupted) {
5200
0
    thread_data->error_info.setjmp = 0;
5201
0
#if CONFIG_MULTITHREAD
5202
0
    pthread_mutex_lock(pbi->row_mt_mutex_);
5203
0
#endif
5204
0
    frame_row_mt_info->row_mt_exit = 1;
5205
0
#if CONFIG_MULTITHREAD
5206
0
    pthread_cond_broadcast(pbi->row_mt_cond_);
5207
0
    pthread_mutex_unlock(pbi->row_mt_mutex_);
5208
0
#endif
5209
0
    return 0;
5210
0
  }
5211
5212
0
  set_decode_func_pointers(td, 0x2);
5213
5214
0
  while (1) {
5215
0
    AV2DecRowMTJobInfo next_job_info;
5216
0
    int end_of_frame = 0;
5217
5218
0
#if CONFIG_MULTITHREAD
5219
0
    pthread_mutex_lock(pbi->row_mt_mutex_);
5220
0
#endif
5221
0
    while (!get_next_job_info(pbi, &next_job_info, &end_of_frame)) {
5222
0
#if CONFIG_MULTITHREAD
5223
0
      pthread_cond_wait(pbi->row_mt_cond_, pbi->row_mt_mutex_);
5224
0
#endif
5225
0
    }
5226
0
#if CONFIG_MULTITHREAD
5227
0
    pthread_mutex_unlock(pbi->row_mt_mutex_);
5228
0
#endif
5229
5230
0
    if (end_of_frame) break;
5231
5232
0
    int tile_row = next_job_info.tile_row;
5233
0
    int tile_col = next_job_info.tile_col;
5234
0
    int mi_row = next_job_info.mi_row;
5235
5236
0
    TileDataDec *tile_data =
5237
0
        pbi->tile_data + tile_row * cm->tiles.cols + tile_col;
5238
0
    AV2DecRowMTSync *dec_row_mt_sync = &tile_data->dec_row_mt_sync;
5239
0
    TileInfo tile_info = tile_data->tile_info;
5240
5241
0
    av2_tile_init(&td->dcb.xd.tile, cm, tile_row, tile_col);
5242
0
    av2_init_macroblockd(cm, &td->dcb.xd);
5243
0
    td->dcb.xd.error_info = &thread_data->error_info;
5244
5245
0
    td->dcb.xd.tile.tile_active_mode = 1;
5246
0
    if (cm->bru.enabled && (cm->tiles.cols * cm->tiles.rows > 1)) {
5247
0
      td->dcb.xd.tile.tile_active_mode = tile_data->tile_info.tile_active_mode;
5248
0
    }
5249
0
    decode_tile_sb_row(pbi, td, tile_info, mi_row);
5250
5251
0
#if CONFIG_MULTITHREAD
5252
0
    pthread_mutex_lock(pbi->row_mt_mutex_);
5253
0
#endif
5254
0
    dec_row_mt_sync->num_threads_working--;
5255
0
#if CONFIG_MULTITHREAD
5256
0
    pthread_mutex_unlock(pbi->row_mt_mutex_);
5257
0
#endif
5258
0
  }
5259
0
  thread_data->error_info.setjmp = 0;
5260
0
  return !td->dcb.corrupted;
5261
0
}
5262
5263
// sorts in descending order
5264
87.6k
static int compare_tile_buffers(const void *a, const void *b) {
5265
87.6k
  const TileJobsDec *const buf1 = (const TileJobsDec *)a;
5266
87.6k
  const TileJobsDec *const buf2 = (const TileJobsDec *)b;
5267
87.6k
  return (((int)buf2->tile_buffer->size) - ((int)buf1->tile_buffer->size));
5268
87.6k
}
5269
5270
static AVM_INLINE void enqueue_tile_jobs(AV2Decoder *pbi, AV2_COMMON *cm,
5271
                                         int tile_rows_start, int tile_rows_end,
5272
                                         int tile_cols_start, int tile_cols_end,
5273
1.46k
                                         int start_tile, int end_tile) {
5274
1.46k
  AV2DecTileMT *tile_mt_info = &pbi->tile_mt_info;
5275
1.46k
  TileJobsDec *tile_job_queue = tile_mt_info->job_queue;
5276
1.46k
  tile_mt_info->jobs_enqueued = 0;
5277
1.46k
  tile_mt_info->jobs_dequeued = 0;
5278
5279
9.73k
  for (int row = tile_rows_start; row < tile_rows_end; row++) {
5280
36.0k
    for (int col = tile_cols_start; col < tile_cols_end; col++) {
5281
27.8k
      if (row * cm->tiles.cols + col < start_tile ||
5282
27.8k
          row * cm->tiles.cols + col > end_tile)
5283
0
        continue;
5284
27.8k
      tile_job_queue->tile_buffer = &pbi->tile_buffers[row][col];
5285
27.8k
      tile_job_queue->tile_data = pbi->tile_data + row * cm->tiles.cols + col;
5286
27.8k
      tile_job_queue++;
5287
27.8k
      tile_mt_info->jobs_enqueued++;
5288
27.8k
    }
5289
8.26k
  }
5290
1.46k
}
5291
5292
static AVM_INLINE void alloc_dec_jobs(AV2DecTileMT *tile_mt_info,
5293
                                      AV2_COMMON *cm, int tile_rows,
5294
886
                                      int tile_cols) {
5295
886
  tile_mt_info->alloc_tile_rows = tile_rows;
5296
886
  tile_mt_info->alloc_tile_cols = tile_cols;
5297
886
  int num_tiles = tile_rows * tile_cols;
5298
886
#if CONFIG_MULTITHREAD
5299
886
  {
5300
886
    CHECK_MEM_ERROR(cm, tile_mt_info->job_mutex,
5301
886
                    avm_malloc(sizeof(*tile_mt_info->job_mutex) * num_tiles));
5302
5303
26.8k
    for (int i = 0; i < num_tiles; i++) {
5304
26.0k
      pthread_mutex_init(&tile_mt_info->job_mutex[i], NULL);
5305
26.0k
    }
5306
886
  }
5307
886
#endif
5308
886
  CHECK_MEM_ERROR(cm, tile_mt_info->job_queue,
5309
886
                  avm_malloc(sizeof(*tile_mt_info->job_queue) * num_tiles));
5310
886
}
5311
5312
72.5k
void av2_free_mc_tmp_buf(ThreadData *thread_data) {
5313
72.5k
  int ref;
5314
217k
  for (ref = 0; ref < 2; ref++) {
5315
145k
    avm_free(thread_data->mc_buf[ref]);
5316
145k
    thread_data->mc_buf[ref] = NULL;
5317
145k
  }
5318
72.5k
  thread_data->mc_buf_size = 0;
5319
5320
72.5k
  avm_free(thread_data->tmp_conv_dst);
5321
72.5k
  thread_data->tmp_conv_dst = NULL;
5322
72.5k
}
5323
5324
// Free-up the temporary buffers created for SMVR and OPFL processing.
5325
72.5k
void av2_free_opfl_tmp_bufs(ThreadData *thread_data) {
5326
72.5k
  avm_free(thread_data->opfl_vxy_bufs);
5327
72.5k
  thread_data->opfl_vxy_bufs = NULL;
5328
5329
72.5k
  avm_free(thread_data->opfl_gxy_bufs);
5330
72.5k
  thread_data->opfl_gxy_bufs = NULL;
5331
5332
72.5k
  avm_free(thread_data->opfl_dst_bufs);
5333
72.5k
  thread_data->opfl_dst_bufs = NULL;
5334
72.5k
}
5335
5336
// Allocate memory for temporary buffers used during the SMVR and OPFL
5337
// processing.
5338
static AVM_INLINE void allocate_opfl_tmp_bufs(AV2_COMMON *const cm,
5339
36.0k
                                              ThreadData *thread_data) {
5340
36.0k
  CHECK_MEM_ERROR(
5341
36.0k
      cm, thread_data->opfl_vxy_bufs,
5342
36.0k
      avm_memalign(32, N_OF_OFFSETS * 4 * sizeof(*thread_data->opfl_vxy_bufs)));
5343
5344
36.0k
  CHECK_MEM_ERROR(cm, thread_data->opfl_gxy_bufs,
5345
36.0k
                  avm_memalign(32, MAX_SB_SQUARE * 4 *
5346
36.0k
                                       sizeof(*thread_data->opfl_gxy_bufs)));
5347
5348
36.0k
  CHECK_MEM_ERROR(cm, thread_data->opfl_dst_bufs,
5349
36.0k
                  avm_memalign(32, MAX_SB_SQUARE * 2 *
5350
36.0k
                                       sizeof(*thread_data->opfl_dst_bufs)));
5351
36.0k
}
5352
5353
static AVM_INLINE void allocate_mc_tmp_buf(AV2_COMMON *const cm,
5354
                                           ThreadData *thread_data,
5355
36.0k
                                           int buf_size) {
5356
108k
  for (int ref = 0; ref < 2; ref++) {
5357
    // The mc_buf/hbd_mc_buf must be zeroed to fix a intermittent valgrind error
5358
    // 'Conditional jump or move depends on uninitialised value' from the loop
5359
    // filter. Uninitialized reads in convolve function (e.g. horiz_4tap path in
5360
    // av2_convolve_2d_sr_avx2()) from mc_buf/hbd_mc_buf are seen to be the
5361
    // potential reason for this issue.
5362
72.0k
    uint16_t *hbd_mc_buf;
5363
72.0k
    CHECK_MEM_ERROR(cm, hbd_mc_buf, (uint16_t *)avm_memalign(16, buf_size));
5364
72.0k
    memset(hbd_mc_buf, 0, buf_size);
5365
72.0k
    thread_data->mc_buf[ref] = hbd_mc_buf;
5366
72.0k
  }
5367
36.0k
  thread_data->mc_buf_size = buf_size;
5368
5369
36.0k
  CHECK_MEM_ERROR(cm, thread_data->tmp_conv_dst,
5370
36.0k
                  avm_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE *
5371
36.0k
                                       sizeof(*thread_data->tmp_conv_dst)));
5372
36.0k
}
5373
5374
static AVM_INLINE void reset_dec_workers(AV2Decoder *pbi,
5375
                                         AVxWorkerHook worker_hook,
5376
1.46k
                                         int num_workers) {
5377
1.46k
  const AVxWorkerInterface *const winterface = avm_get_worker_interface();
5378
5379
  // Reset tile decoding hook
5380
28.7k
  for (int worker_idx = 0; worker_idx < num_workers; ++worker_idx) {
5381
27.3k
    AVxWorker *const worker = &pbi->tile_workers[worker_idx];
5382
27.3k
    DecWorkerData *const thread_data = pbi->thread_data + worker_idx;
5383
27.3k
    thread_data->td->dcb = pbi->dcb;
5384
27.3k
    thread_data->td->dcb.corrupted = 0;
5385
27.3k
    thread_data->td->dcb.mc_buf[0] = thread_data->td->mc_buf[0];
5386
27.3k
    thread_data->td->dcb.mc_buf[1] = thread_data->td->mc_buf[1];
5387
27.3k
    thread_data->td->dcb.xd.tmp_conv_dst = thread_data->td->tmp_conv_dst;
5388
    // Temporary buffers used during the SMVR and OPFL processing.
5389
27.3k
    thread_data->td->dcb.xd.opfl_vxy_bufs = thread_data->td->opfl_vxy_bufs;
5390
27.3k
    thread_data->td->dcb.xd.opfl_gxy_bufs = thread_data->td->opfl_gxy_bufs;
5391
27.3k
    thread_data->td->dcb.xd.opfl_dst_bufs = thread_data->td->opfl_dst_bufs;
5392
5393
27.3k
    winterface->sync(worker);
5394
5395
27.3k
    worker->hook = worker_hook;
5396
27.3k
    worker->data1 = thread_data;
5397
27.3k
    worker->data2 = pbi;
5398
27.3k
  }
5399
#if CONFIG_ACCOUNTING
5400
  if (pbi->acct_enabled) {
5401
#if CONFIG_THROUGHPUT_ANALYSIS
5402
    avm_accounting_cal_total(pbi);
5403
#else
5404
    avm_accounting_dump(&pbi->accounting);
5405
#endif  // CONFIG_THROUGHPUT_ANALYSIS
5406
    avm_accounting_reset(&pbi->accounting);
5407
  }
5408
#endif
5409
1.46k
}
5410
5411
static AVM_INLINE void launch_dec_workers(AV2Decoder *pbi,
5412
                                          const uint8_t *data_end,
5413
1.46k
                                          int num_workers) {
5414
1.46k
  const AVxWorkerInterface *const winterface = avm_get_worker_interface();
5415
5416
28.7k
  for (int worker_idx = 0; worker_idx < num_workers; ++worker_idx) {
5417
27.3k
    AVxWorker *const worker = &pbi->tile_workers[worker_idx];
5418
27.3k
    DecWorkerData *const thread_data = (DecWorkerData *)worker->data1;
5419
5420
27.3k
    thread_data->data_end = data_end;
5421
5422
27.3k
    worker->had_error = 0;
5423
27.3k
    if (worker_idx == num_workers - 1) {
5424
1.46k
      winterface->execute(worker);
5425
25.8k
    } else {
5426
25.8k
      winterface->launch(worker);
5427
25.8k
    }
5428
27.3k
  }
5429
1.46k
}
5430
5431
1.46k
static AVM_INLINE void sync_dec_workers(AV2Decoder *pbi, int num_workers) {
5432
1.46k
  const AVxWorkerInterface *const winterface = avm_get_worker_interface();
5433
1.46k
  int corrupted = 0;
5434
5435
28.7k
  for (int worker_idx = num_workers; worker_idx > 0; --worker_idx) {
5436
27.3k
    AVxWorker *const worker = &pbi->tile_workers[worker_idx - 1];
5437
27.3k
    avm_merge_corrupted_flag(&corrupted, !winterface->sync(worker));
5438
27.3k
  }
5439
5440
1.46k
  pbi->dcb.corrupted = corrupted;
5441
1.46k
}
5442
5443
1.57k
static AVM_INLINE void decode_mt_init(AV2Decoder *pbi) {
5444
1.57k
  AV2_COMMON *const cm = &pbi->common;
5445
1.57k
  const AVxWorkerInterface *const winterface = avm_get_worker_interface();
5446
1.57k
  int worker_idx;
5447
5448
  // Create workers and thread_data
5449
1.57k
  if (pbi->num_workers == 0) {
5450
898
    const int num_threads = pbi->max_threads;
5451
898
    CHECK_MEM_ERROR(cm, pbi->tile_workers,
5452
898
                    avm_malloc(num_threads * sizeof(*pbi->tile_workers)));
5453
898
    CHECK_MEM_ERROR(cm, pbi->thread_data,
5454
898
                    avm_malloc(num_threads * sizeof(*pbi->thread_data)));
5455
5456
35.8k
    for (worker_idx = 0; worker_idx < num_threads; ++worker_idx) {
5457
34.9k
      AVxWorker *const worker = &pbi->tile_workers[worker_idx];
5458
34.9k
      DecWorkerData *const thread_data = pbi->thread_data + worker_idx;
5459
34.9k
      ++pbi->num_workers;
5460
5461
34.9k
      winterface->init(worker);
5462
34.9k
      worker->thread_name = "avm tile worker";
5463
34.9k
      if (worker_idx < num_threads - 1 && !winterface->reset(worker)) {
5464
0
        avm_internal_error(&cm->error, AVM_CODEC_ERROR,
5465
0
                           "Tile decoder thread creation failed");
5466
0
      }
5467
5468
34.9k
      if (worker_idx < num_threads - 1) {
5469
        // Allocate thread data.
5470
34.0k
        CHECK_MEM_ERROR(cm, thread_data->td,
5471
34.0k
                        avm_memalign(32, sizeof(*thread_data->td)));
5472
34.0k
        av2_zero(*thread_data->td);
5473
34.0k
      } else {
5474
        // Main thread acts as a worker and uses the thread data in pbi
5475
898
        thread_data->td = &pbi->td;
5476
898
      }
5477
34.9k
      thread_data->error_info.error_code = AVM_CODEC_OK;
5478
34.9k
      thread_data->error_info.setjmp = 0;
5479
34.9k
    }
5480
898
  }
5481
1.57k
  const int buf_size = MC_TEMP_BUF_PELS << 1;
5482
75.5k
  for (worker_idx = 0; worker_idx < pbi->max_threads - 1; ++worker_idx) {
5483
74.0k
    DecWorkerData *const thread_data = pbi->thread_data + worker_idx;
5484
74.0k
    if (thread_data->td->mc_buf_size != buf_size) {
5485
34.0k
      av2_free_mc_tmp_buf(thread_data->td);
5486
34.0k
      av2_free_opfl_tmp_bufs(thread_data->td);
5487
5488
34.0k
      allocate_mc_tmp_buf(cm, thread_data->td, buf_size);
5489
34.0k
      allocate_opfl_tmp_bufs(cm, thread_data->td);
5490
34.0k
    }
5491
74.0k
  }
5492
1.57k
}
5493
5494
static AVM_INLINE void tile_mt_queue(AV2Decoder *pbi, int tile_cols,
5495
                                     int tile_rows, int tile_rows_start,
5496
                                     int tile_rows_end, int tile_cols_start,
5497
                                     int tile_cols_end, int start_tile,
5498
1.46k
                                     int end_tile) {
5499
1.46k
  AV2_COMMON *const cm = &pbi->common;
5500
1.46k
  if (pbi->tile_mt_info.alloc_tile_cols != tile_cols ||
5501
886
      pbi->tile_mt_info.alloc_tile_rows != tile_rows) {
5502
886
    av2_dealloc_dec_jobs(&pbi->tile_mt_info);
5503
886
    alloc_dec_jobs(&pbi->tile_mt_info, cm, tile_rows, tile_cols);
5504
886
  }
5505
1.46k
  enqueue_tile_jobs(pbi, cm, tile_rows_start, tile_rows_end, tile_cols_start,
5506
1.46k
                    tile_cols_end, start_tile, end_tile);
5507
1.46k
  qsort(pbi->tile_mt_info.job_queue, pbi->tile_mt_info.jobs_enqueued,
5508
1.46k
        sizeof(pbi->tile_mt_info.job_queue[0]), compare_tile_buffers);
5509
1.46k
}
5510
5511
static const uint8_t *decode_tiles_mt(AV2Decoder *pbi, const uint8_t *data,
5512
                                      const uint8_t *data_end, int start_tile,
5513
1.57k
                                      int end_tile) {
5514
1.57k
  AV2_COMMON *const cm = &pbi->common;
5515
1.57k
  CommonTileParams *const tiles = &cm->tiles;
5516
1.57k
  const int tile_cols = tiles->cols;
5517
1.57k
  const int tile_rows = tiles->rows;
5518
1.57k
  const int n_tiles = tile_cols * tile_rows;
5519
1.57k
  TileBufferDec(*const tile_buffers)[MAX_TILE_COLS] = pbi->tile_buffers;
5520
1.57k
  int tile_rows_start;
5521
1.57k
  int tile_rows_end;
5522
1.57k
  int tile_cols_start;
5523
1.57k
  int tile_cols_end;
5524
1.57k
  int tile_count_tg;
5525
1.57k
  int num_workers;
5526
5527
1.57k
  tile_rows_start = 0;
5528
1.57k
  tile_rows_end = tile_rows;
5529
1.57k
  tile_cols_start = 0;
5530
1.57k
  tile_cols_end = tile_cols;
5531
5532
1.57k
  tile_count_tg = end_tile - start_tile + 1;
5533
1.57k
  num_workers = AVMMIN(pbi->max_threads, tile_count_tg);
5534
5535
  // No tiles to decode.
5536
1.57k
  if (tile_rows_end <= tile_rows_start || tile_cols_end <= tile_cols_start ||
5537
      // First tile is larger than end_tile.
5538
1.57k
      tile_rows_start * tile_cols + tile_cols_start > end_tile ||
5539
      // Last tile is smaller than start_tile.
5540
1.57k
      (tile_rows_end - 1) * tile_cols + tile_cols_end - 1 < start_tile)
5541
0
    return data;
5542
5543
1.57k
  assert(tile_rows <= MAX_TILE_ROWS);
5544
1.57k
  assert(tile_cols <= MAX_TILE_COLS);
5545
1.57k
  assert(tile_count_tg > 0);
5546
1.57k
  assert(num_workers > 0);
5547
1.57k
  assert(start_tile <= end_tile);
5548
1.57k
  assert(start_tile >= 0 && end_tile < n_tiles);
5549
5550
1.57k
  decode_mt_init(pbi);
5551
1.57k
  if (pbi->tile_data == NULL || n_tiles != pbi->allocated_tiles) {
5552
912
    decoder_alloc_tile_data(pbi, n_tiles);
5553
912
  }
5554
  // get tile size in tile group
5555
1.57k
  get_tile_buffers(pbi, data, data_end, tile_buffers, start_tile, end_tile);
5556
5557
9.84k
  for (int row = 0; row < tile_rows; row++) {
5558
36.0k
    for (int col = 0; col < tile_cols; col++) {
5559
27.8k
      TileDataDec *tile_data = pbi->tile_data + row * tiles->cols + col;
5560
27.8k
      av2_tile_init(&tile_data->tile_info, cm, row, col);
5561
27.8k
    }
5562
8.26k
  }
5563
5564
1.57k
  tile_mt_queue(pbi, tile_cols, tile_rows, tile_rows_start, tile_rows_end,
5565
1.57k
                tile_cols_start, tile_cols_end, start_tile, end_tile);
5566
5567
1.57k
  reset_dec_workers(pbi, tile_worker_hook, num_workers);
5568
1.57k
  launch_dec_workers(pbi, data_end, num_workers);
5569
1.57k
  sync_dec_workers(pbi, num_workers);
5570
5571
1.57k
  if (pbi->dcb.corrupted)
5572
1.46k
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
5573
1.46k
                       "Failed to decode tile data");
5574
5575
1.57k
  TileDataDec *const tile_data = pbi->tile_data + end_tile;
5576
5577
1.57k
  return avm_reader_find_end(&tile_data->bit_reader);
5578
1.57k
}
5579
5580
0
static AVM_INLINE void dec_alloc_cb_buf(AV2Decoder *pbi) {
5581
0
  AV2_COMMON *const cm = &pbi->common;
5582
0
  int size = ((cm->mi_params.mi_rows >> cm->mib_size_log2) + 1) *
5583
0
             ((cm->mi_params.mi_cols >> cm->mib_size_log2) + 1);
5584
5585
0
  if (pbi->cb_buffer_alloc_size < size) {
5586
0
    av2_dec_free_cb_buf(pbi);
5587
0
    CHECK_MEM_ERROR(cm, pbi->cb_buffer_base,
5588
0
                    avm_memalign(32, sizeof(*pbi->cb_buffer_base) * size));
5589
0
    memset(pbi->cb_buffer_base, 0, sizeof(*pbi->cb_buffer_base) * size);
5590
0
    pbi->cb_buffer_alloc_size = size;
5591
0
  }
5592
0
}
5593
5594
static AVM_INLINE void row_mt_frame_init(AV2Decoder *pbi, int tile_rows_start,
5595
                                         int tile_rows_end, int tile_cols_start,
5596
                                         int tile_cols_end, int start_tile,
5597
0
                                         int end_tile, int max_sb_rows) {
5598
0
  AV2_COMMON *const cm = &pbi->common;
5599
0
  AV2DecRowMTInfo *frame_row_mt_info = &pbi->frame_row_mt_info;
5600
5601
0
  frame_row_mt_info->tile_rows_start = tile_rows_start;
5602
0
  frame_row_mt_info->tile_rows_end = tile_rows_end;
5603
0
  frame_row_mt_info->tile_cols_start = tile_cols_start;
5604
0
  frame_row_mt_info->tile_cols_end = tile_cols_end;
5605
0
  frame_row_mt_info->start_tile = start_tile;
5606
0
  frame_row_mt_info->end_tile = end_tile;
5607
0
  frame_row_mt_info->mi_rows_to_decode = 0;
5608
0
  frame_row_mt_info->mi_rows_parse_done = 0;
5609
0
  frame_row_mt_info->mi_rows_decode_started = 0;
5610
0
  frame_row_mt_info->row_mt_exit = 0;
5611
5612
0
  for (int tile_row = tile_rows_start; tile_row < tile_rows_end; ++tile_row) {
5613
0
    for (int tile_col = tile_cols_start; tile_col < tile_cols_end; ++tile_col) {
5614
0
      if (tile_row * cm->tiles.cols + tile_col < start_tile ||
5615
0
          tile_row * cm->tiles.cols + tile_col > end_tile)
5616
0
        continue;
5617
5618
0
      TileDataDec *const tile_data =
5619
0
          pbi->tile_data + tile_row * cm->tiles.cols + tile_col;
5620
0
      TileInfo tile_info = tile_data->tile_info;
5621
5622
0
      tile_data->dec_row_mt_sync.mi_rows_parse_done = 0;
5623
0
      tile_data->dec_row_mt_sync.mi_rows_decode_started = 0;
5624
0
      tile_data->dec_row_mt_sync.num_threads_working = 0;
5625
0
      tile_data->dec_row_mt_sync.mi_rows = ALIGN_POWER_OF_TWO(
5626
0
          tile_info.mi_row_end - tile_info.mi_row_start, cm->mib_size_log2);
5627
0
      tile_data->dec_row_mt_sync.mi_cols = ALIGN_POWER_OF_TWO(
5628
0
          tile_info.mi_col_end - tile_info.mi_col_start, cm->mib_size_log2);
5629
5630
0
      frame_row_mt_info->mi_rows_to_decode +=
5631
0
          tile_data->dec_row_mt_sync.mi_rows;
5632
5633
      // Initialize cur_sb_col to -1 for all SB rows.
5634
0
      memset(tile_data->dec_row_mt_sync.cur_sb_col, -1,
5635
0
             sizeof(*tile_data->dec_row_mt_sync.cur_sb_col) * max_sb_rows);
5636
0
    }
5637
0
  }
5638
5639
0
#if CONFIG_MULTITHREAD
5640
0
  if (pbi->row_mt_mutex_ == NULL) {
5641
0
    CHECK_MEM_ERROR(cm, pbi->row_mt_mutex_,
5642
0
                    avm_malloc(sizeof(*(pbi->row_mt_mutex_))));
5643
0
    if (pbi->row_mt_mutex_) {
5644
0
      pthread_mutex_init(pbi->row_mt_mutex_, NULL);
5645
0
    }
5646
0
  }
5647
5648
0
  if (pbi->row_mt_cond_ == NULL) {
5649
0
    CHECK_MEM_ERROR(cm, pbi->row_mt_cond_,
5650
0
                    avm_malloc(sizeof(*(pbi->row_mt_cond_))));
5651
0
    if (pbi->row_mt_cond_) {
5652
0
      pthread_cond_init(pbi->row_mt_cond_, NULL);
5653
0
    }
5654
0
  }
5655
0
#endif
5656
0
}
5657
5658
static const uint8_t *decode_tiles_row_mt(AV2Decoder *pbi, const uint8_t *data,
5659
                                          const uint8_t *data_end,
5660
0
                                          int start_tile, int end_tile) {
5661
0
  AV2_COMMON *const cm = &pbi->common;
5662
0
  CommonTileParams *const tiles = &cm->tiles;
5663
0
  const int tile_cols = tiles->cols;
5664
0
  const int tile_rows = tiles->rows;
5665
0
  const int n_tiles = tile_cols * tile_rows;
5666
0
  TileBufferDec(*const tile_buffers)[MAX_TILE_COLS] = pbi->tile_buffers;
5667
0
  int tile_rows_start;
5668
0
  int tile_rows_end;
5669
0
  int tile_cols_start;
5670
0
  int tile_cols_end;
5671
0
  int tile_count_tg;
5672
0
  int num_workers = 0;
5673
0
  int max_threads;
5674
0
  int max_sb_rows = 0;
5675
5676
0
  tile_rows_start = 0;
5677
0
  tile_rows_end = tile_rows;
5678
0
  tile_cols_start = 0;
5679
0
  tile_cols_end = tile_cols;
5680
5681
0
  tile_count_tg = end_tile - start_tile + 1;
5682
0
  max_threads = pbi->max_threads;
5683
5684
  // No tiles to decode.
5685
0
  if (tile_rows_end <= tile_rows_start || tile_cols_end <= tile_cols_start ||
5686
      // First tile is larger than end_tile.
5687
0
      tile_rows_start * tile_cols + tile_cols_start > end_tile ||
5688
      // Last tile is smaller than start_tile.
5689
0
      (tile_rows_end - 1) * tile_cols + tile_cols_end - 1 < start_tile)
5690
0
    return data;
5691
5692
0
  assert(tile_rows <= MAX_TILE_ROWS);
5693
0
  assert(tile_cols <= MAX_TILE_COLS);
5694
0
  assert(tile_count_tg > 0);
5695
0
  assert(max_threads > 0);
5696
0
  assert(start_tile <= end_tile);
5697
0
  assert(start_tile >= 0 && end_tile < n_tiles);
5698
5699
0
  (void)tile_count_tg;
5700
5701
0
  decode_mt_init(pbi);
5702
5703
0
  if (pbi->tile_data == NULL || n_tiles != pbi->allocated_tiles) {
5704
0
    if (pbi->tile_data != NULL) {
5705
0
      for (int i = 0; i < pbi->allocated_tiles; i++) {
5706
0
        TileDataDec *const tile_data = pbi->tile_data + i;
5707
0
        av2_dec_row_mt_dealloc(&tile_data->dec_row_mt_sync);
5708
0
      }
5709
0
    }
5710
0
    decoder_alloc_tile_data(pbi, n_tiles);
5711
0
  }
5712
5713
  // get tile size in tile group
5714
0
  get_tile_buffers(pbi, data, data_end, tile_buffers, start_tile, end_tile);
5715
5716
0
  for (int row = 0; row < tile_rows; row++) {
5717
0
    for (int col = 0; col < tile_cols; col++) {
5718
0
      TileDataDec *tile_data = pbi->tile_data + row * tiles->cols + col;
5719
0
      av2_tile_init(&tile_data->tile_info, cm, row, col);
5720
5721
0
      max_sb_rows = AVMMAX(max_sb_rows,
5722
0
                           av2_get_sb_rows_in_tile(cm, tile_data->tile_info));
5723
0
      num_workers += get_max_row_mt_workers_per_tile(cm, tile_data->tile_info);
5724
0
    }
5725
0
  }
5726
0
  num_workers = AVMMIN(num_workers, max_threads);
5727
5728
0
  if (pbi->allocated_row_mt_sync_rows != max_sb_rows) {
5729
0
    for (int i = 0; i < n_tiles; ++i) {
5730
0
      TileDataDec *const tile_data = pbi->tile_data + i;
5731
0
      av2_dec_row_mt_dealloc(&tile_data->dec_row_mt_sync);
5732
0
      dec_row_mt_alloc(&tile_data->dec_row_mt_sync, cm, max_sb_rows);
5733
0
    }
5734
0
    pbi->allocated_row_mt_sync_rows = max_sb_rows;
5735
0
  }
5736
5737
0
  tile_mt_queue(pbi, tile_cols, tile_rows, tile_rows_start, tile_rows_end,
5738
0
                tile_cols_start, tile_cols_end, start_tile, end_tile);
5739
5740
0
  dec_alloc_cb_buf(pbi);
5741
5742
0
  row_mt_frame_init(pbi, tile_rows_start, tile_rows_end, tile_cols_start,
5743
0
                    tile_cols_end, start_tile, end_tile, max_sb_rows);
5744
5745
0
  reset_dec_workers(pbi, row_mt_worker_hook, num_workers);
5746
0
  launch_dec_workers(pbi, data_end, num_workers);
5747
0
  sync_dec_workers(pbi, num_workers);
5748
5749
0
  if (pbi->dcb.corrupted)
5750
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
5751
0
                       "Failed to decode tile data");
5752
5753
0
  TileDataDec *const tile_data = pbi->tile_data + end_tile;
5754
5755
0
  return avm_reader_find_end(&tile_data->bit_reader);
5756
0
}
5757
5758
static AVM_INLINE void error_handler(void *data, avm_codec_err_t error,
5759
7.56k
                                     const char *detail) {
5760
7.56k
  AV2_COMMON *const cm = (AV2_COMMON *)data;
5761
7.56k
  avm_internal_error(&cm->error, error, detail);
5762
7.56k
}
5763
5764
// Gets the bitdepth_lut_idx field in color_config() and returns bit_depth from
5765
// the bitdepth list.
5766
61.2k
int av2_get_bitdepth_from_index(uint32_t bitdepth_lut_idx) {
5767
61.2k
  static avm_bit_depth_t bitdepth_list[] = { AVM_BITS_10, AVM_BITS_8,
5768
61.2k
                                             AVM_BITS_12 };
5769
61.2k
  if (bitdepth_lut_idx >= AVM_NUM_SUPPORTED_BITDEPTH) return -1;
5770
61.2k
  return bitdepth_list[bitdepth_lut_idx];
5771
61.2k
}
5772
// Reads the bitdepth in color_config() and sets seq_params->bit_depth
5773
// Reports errors by calling rb->error_handler() or
5774
// avm_internal_error().
5775
static AVM_INLINE void read_bitdepth(
5776
    struct avm_read_bit_buffer *rb, SequenceHeader *seq_params,
5777
22.0k
    struct avm_internal_error_info *error_info) {
5778
22.0k
  const uint32_t bitdepth_lut_idx = avm_rb_read_uvlc(rb);
5779
22.0k
  const int bitdepth = av2_get_bitdepth_from_index(bitdepth_lut_idx);
5780
22.0k
  if (bitdepth >= 0)
5781
22.0k
    seq_params->bit_depth = bitdepth;
5782
0
  else {
5783
0
    avm_internal_error(error_info, AVM_CODEC_UNSUP_BITSTREAM,
5784
0
                       "Unsupported profile/bit-depth combination");
5785
0
  }
5786
22.0k
}
5787
8.90k
static void setup_film_grain(AV2Decoder *pbi, struct avm_read_bit_buffer *rb) {
5788
8.90k
  AV2_COMMON *const cm = &pbi->common;
5789
8.90k
  const SequenceHeader *const seq_params = &cm->seq_params;
5790
8.90k
  memset(&cm->film_grain_params, 0, sizeof(cm->film_grain_params));
5791
  // NOTE: immediate_output_picture is 1 when cm->show_existing_frame
5792
8.90k
  if (seq_params->film_grain_params_present &&
5793
6.23k
      (cm->immediate_output_picture || cm->implicit_output_picture)) {
5794
6.23k
    avm_film_grain_t *pars = &cm->film_grain_params;
5795
6.23k
    if (cm->seq_params.single_picture_header_flag) {
5796
6.23k
      pars->apply_grain = 1;
5797
6.23k
    } else {
5798
1
      pars->apply_grain = avm_rb_read_bit(rb);
5799
1
    }
5800
6.23k
    if (pars->apply_grain) {
5801
6.23k
      cm->fgm_id = avm_rb_read_literal(rb, FGM_ID_BITS);
5802
6.23k
      pars->random_seed = avm_rb_read_literal(rb, 16);
5803
6.23k
      pars->update_parameters = 1;
5804
6.23k
      if (pbi->fgm_list[cm->fgm_id].fgm_id < 0) {
5805
4.52k
        avm_internal_error(&cm->error, AVM_CODEC_INVALID_PARAM,
5806
4.52k
                           "fgm_list[%d] is unavailable", cm->fgm_id);
5807
4.52k
      }
5808
6.23k
      if (!seq_params->mlayer_dependency_map
5809
6.23k
               [cm->mlayer_id][pbi->fgm_list[cm->fgm_id].fgm_mlayer_id] ||
5810
1.70k
          !seq_params->tlayer_dependency_map[cm->mlayer_id][cm->tlayer_id]
5811
1.70k
                                            [pbi->fgm_list[cm->fgm_id]
5812
1.70k
                                                 .fgm_tlayer_id]) {
5813
88
        avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
5814
88
                           "mlayer_id(%d) or tlayer_id(%d) of the film grain "
5815
88
                           "model is out of the limit",
5816
88
                           pbi->fgm_list[cm->fgm_id].fgm_mlayer_id,
5817
88
                           pbi->fgm_list[cm->fgm_id].fgm_tlayer_id);
5818
88
      }
5819
6.23k
      uint32_t seq_chroma_format_idc = CHROMA_FORMAT_420;
5820
6.23k
      avm_codec_err_t err = av2_get_chroma_format_idc(
5821
6.23k
          seq_params->subsampling_x, seq_params->subsampling_y,
5822
6.23k
          seq_params->monochrome, &seq_chroma_format_idc);
5823
6.23k
      if (err != AVM_CODEC_OK) {
5824
0
        avm_internal_error(
5825
0
            &cm->error, err,
5826
0
            "Unsupported subsampling_x = %d, subsampling_y = %d.",
5827
0
            seq_params->subsampling_x, seq_params->subsampling_y);
5828
0
      }
5829
6.23k
      if (seq_chroma_format_idc !=
5830
6.23k
          (uint32_t)pbi->fgm_list[cm->fgm_id].fgm_chroma_idc) {
5831
2
        avm_internal_error(
5832
2
            &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
5833
2
            "chroma_format_idc(%d) of fgm_list[%d] is different from "
5834
2
            "chroma_format_idc(%d) in the sequence header",
5835
2
            pbi->fgm_list[cm->fgm_id].fgm_chroma_idc, cm->fgm_id,
5836
2
            seq_chroma_format_idc);
5837
2
      }
5838
6.23k
      copy_fgm_from_list(cm, pars, &pbi->fgm_list[cm->fgm_id]);
5839
6.23k
    }
5840
6.23k
  }
5841
8.90k
  cm->cur_frame->film_grain_params = cm->film_grain_params;
5842
8.90k
}
5843
5844
// Given chroma_format_idc, set the subsampling_x/y values in `seq_params`.
5845
// Calls `avm_internal_error` in case of invalid chroma_format_idc.
5846
static void set_seq_chroma_format(uint32_t seq_chroma_format_idc,
5847
                                  SequenceHeader *seq_params,
5848
22.0k
                                  struct avm_internal_error_info *error_info) {
5849
22.0k
  avm_codec_err_t err = av2_get_chroma_subsampling(seq_chroma_format_idc,
5850
22.0k
                                                   &seq_params->subsampling_x,
5851
22.0k
                                                   &seq_params->subsampling_y);
5852
22.0k
  if (err != AVM_CODEC_OK) {
5853
0
    avm_internal_error(
5854
0
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
5855
0
        "Only 4:0:0, 4:4:4, 4:2:2 and 4:2:0 are currently supported. "
5856
0
        "Invalid chroma_format_idc value: %d.\n",
5857
0
        seq_chroma_format_idc);
5858
0
  }
5859
22.0k
}
5860
5861
void av2_read_chroma_format_bitdepth(
5862
    struct avm_read_bit_buffer *rb, SequenceHeader *seq_params,
5863
22.0k
    struct avm_internal_error_info *error_info) {
5864
22.0k
  const uint32_t seq_chroma_format_idc = avm_rb_read_uvlc(rb);
5865
22.0k
  set_seq_chroma_format(seq_chroma_format_idc, seq_params, error_info);
5866
5867
22.0k
  read_bitdepth(rb, seq_params, error_info);
5868
5869
22.0k
  const int is_monochrome = (seq_chroma_format_idc == CHROMA_FORMAT_400);
5870
22.0k
  seq_params->monochrome = is_monochrome;
5871
22.0k
}
5872
5873
void av2_read_timing_info_header(avm_timing_info_t *timing_info,
5874
                                 struct avm_internal_error_info *error,
5875
15
                                 struct avm_read_bit_buffer *rb) {
5876
15
  timing_info->num_units_in_display_tick =
5877
15
      avm_rb_read_unsigned_literal(rb,
5878
15
                                   32);  // Number of units in a display tick
5879
15
  timing_info->time_scale = avm_rb_read_unsigned_literal(rb, 32);  // Time scale
5880
15
  if (timing_info->num_units_in_display_tick == 0 ||
5881
15
      timing_info->time_scale == 0) {
5882
0
    avm_internal_error(
5883
0
        error, AVM_CODEC_UNSUP_BITSTREAM,
5884
0
        "num_units_in_display_tick and time_scale must be greater than 0.");
5885
0
  }
5886
15
  timing_info->equal_elemental_interval =
5887
15
      avm_rb_read_bit(rb);  // Equal picture interval bit
5888
15
  if (timing_info->equal_elemental_interval) {
5889
15
    const uint32_t num_ticks_per_picture_minus_1 = avm_rb_read_uvlc(rb);
5890
15
    if (num_ticks_per_picture_minus_1 == UINT32_MAX) {
5891
0
      avm_internal_error(
5892
0
          error, AVM_CODEC_UNSUP_BITSTREAM,
5893
0
          "num_ticks_per_picture_minus_1 cannot be (1 << 32) − 1.");
5894
0
    }
5895
15
    timing_info->num_ticks_per_elemental_duration =
5896
15
        num_ticks_per_picture_minus_1 + 1;
5897
15
  }
5898
15
}
5899
5900
// This function reads the parameters for the conformance window
5901
void av2_read_conformance_window(struct avm_read_bit_buffer *rb,
5902
21.9k
                                 struct SequenceHeader *seq_params) {
5903
21.9k
  struct CropWindow *conf = &seq_params->conf;
5904
21.9k
  conf->conf_win_enabled_flag = avm_rb_read_bit(rb);
5905
5906
21.9k
  if (conf->conf_win_enabled_flag) {
5907
1.56k
    conf->conf_win_left_offset = avm_rb_read_uvlc(rb);
5908
1.56k
    conf->conf_win_right_offset = avm_rb_read_uvlc(rb);
5909
1.56k
    conf->conf_win_top_offset = avm_rb_read_uvlc(rb);
5910
1.56k
    conf->conf_win_bottom_offset = avm_rb_read_uvlc(rb);
5911
20.3k
  } else {
5912
20.3k
    conf->conf_win_left_offset = 0;
5913
20.3k
    conf->conf_win_right_offset = 0;
5914
20.3k
    conf->conf_win_top_offset = 0;
5915
20.3k
    conf->conf_win_bottom_offset = 0;
5916
20.3k
  }
5917
21.9k
}
5918
5919
// Reads the tile information in the sequence header
5920
static void read_sequence_tile_info(struct SequenceHeader *seq_params,
5921
17.7k
                                    struct avm_read_bit_buffer *rb) {
5922
17.7k
  av2_get_seq_tile_limits(&seq_params->tile_params,
5923
17.7k
                          seq_params->max_frame_height,
5924
17.7k
                          seq_params->max_frame_width,
5925
17.7k
                          seq_params->mib_size_log2, seq_params->mib_size_log2,
5926
17.7k
                          seq_params->seq_max_level_idx, seq_params->seq_tier);
5927
17.7k
  seq_params->tile_params.allow_tile_info_change = avm_rb_read_bit(rb);
5928
17.7k
  read_tile_params(&seq_params->tile_params.tile_info, rb);
5929
17.7k
}
5930
5931
static void read_sequence_tile_config(struct SequenceHeader *seq_params,
5932
21.7k
                                      struct avm_read_bit_buffer *rb) {
5933
21.7k
  seq_params->seq_tile_info_present_flag = avm_rb_read_bit(rb);
5934
21.7k
  if (seq_params->seq_tile_info_present_flag) {
5935
17.7k
    read_sequence_tile_info(seq_params, rb);
5936
17.7k
  }
5937
21.7k
}
5938
5939
static void read_seg_syntax_info(struct SegmentationInfoSyntax *seg_params,
5940
1.05k
                                 struct avm_read_bit_buffer *rb) {
5941
1.05k
  seg_params->allow_seg_info_change = avm_rb_read_bit(rb);
5942
5943
1.05k
  const int max_seg_num =
5944
1.05k
      seg_params->enable_ext_seg ? MAX_SEGMENTS : MAX_SEGMENTS_8;
5945
5946
1.05k
  memset(seg_params->feature_mask, 0, sizeof(seg_params->feature_mask));
5947
1.05k
  memset(seg_params->feature_data, 0, sizeof(seg_params->feature_data));
5948
5949
  // Read segmentation feature data
5950
14.1k
  for (int i = 0; i < max_seg_num; i++) {
5951
52.3k
    for (int j = 0; j < SEG_LVL_MAX; j++) {
5952
39.1k
      const int feature_enabled = avm_rb_read_bit(rb);
5953
39.1k
      if (feature_enabled) {
5954
13.2k
        seg_params->feature_mask[i] |= (1 << j);
5955
5956
13.2k
        const int data_max = av2_seg_feature_data_max(j);
5957
13.2k
        const int data_min = -data_max;
5958
13.2k
        const int ubits = get_unsigned_bits(data_max);
5959
13.2k
        int data = 0;
5960
5961
13.2k
        if (av2_is_segfeature_signed(j)) {
5962
5.48k
          data = avm_rb_read_inv_signed_literal(rb, ubits);
5963
7.74k
        } else {
5964
7.74k
          data = avm_rb_read_literal(rb, ubits);
5965
7.74k
        }
5966
5967
13.2k
        seg_params->feature_data[i][j] = clamp(data, data_min, data_max);
5968
13.2k
      }
5969
39.1k
    }
5970
13.1k
  }
5971
5972
1.05k
  av2_calculate_segdata_from_syntax(seg_params);
5973
1.05k
}
5974
5975
void read_sequence_partition_group_tool_flags(struct SequenceHeader *seq_params,
5976
21.9k
                                              struct avm_read_bit_buffer *rb) {
5977
21.9k
  setup_seq_sb_size(seq_params, rb);
5978
21.9k
  seq_params->enable_sdp = seq_params->monochrome ? 0 : avm_rb_read_bit(rb);
5979
21.9k
  seq_params->enable_extended_sdp =
5980
21.9k
      (seq_params->enable_sdp && !seq_params->single_picture_header_flag)
5981
21.9k
          ? avm_rb_read_bit(rb)
5982
21.9k
          : 0;
5983
21.9k
  seq_params->enable_ext_partitions = avm_rb_read_bit(rb);
5984
21.9k
  if (seq_params->enable_ext_partitions)
5985
17.6k
    seq_params->enable_uneven_4way_partitions = avm_rb_read_bit(rb);
5986
4.22k
  else
5987
4.22k
    seq_params->enable_uneven_4way_partitions = 0;
5988
21.9k
  seq_params->max_pb_aspect_ratio_log2_m1 = 2;
5989
21.9k
  if (avm_rb_read_bit(rb)) {
5990
2.04k
    seq_params->max_pb_aspect_ratio_log2_m1 = avm_rb_read_bit(rb);
5991
2.04k
  }
5992
21.9k
}
5993
5994
void read_sequence_intra_group_tool_flags(struct SequenceHeader *seq_params,
5995
21.7k
                                          struct avm_read_bit_buffer *rb) {
5996
21.7k
  seq_params->enable_intra_dip = avm_rb_read_bit(rb);
5997
21.7k
  seq_params->enable_intra_edge_filter = avm_rb_read_bit(rb);
5998
21.7k
  seq_params->enable_mrls = avm_rb_read_bit(rb);
5999
21.7k
  seq_params->enable_cfl_intra = avm_rb_read_bit(rb);
6000
21.7k
  seq_params->cfl_ds_filter_index =
6001
21.7k
      seq_params->monochrome ? 0 : avm_rb_read_literal(rb, 2);
6002
21.7k
  seq_params->enable_mhccp = avm_rb_read_bit(rb);
6003
21.7k
  seq_params->enable_ibp = avm_rb_read_bit(rb);
6004
21.7k
}
6005
void read_sequence_inter_group_tool_flags(struct SequenceHeader *seq_params,
6006
21.7k
                                          struct avm_read_bit_buffer *rb) {
6007
21.7k
  if (seq_params->single_picture_header_flag) {
6008
19.7k
    seq_params->seq_frame_motion_modes_present_flag = 0;
6009
19.7k
    seq_params->enable_six_param_warp_delta = 0;
6010
19.7k
    seq_params->seq_enabled_motion_modes = (1 << SIMPLE_TRANSLATION);
6011
19.7k
    seq_params->enable_masked_compound = 0;
6012
19.7k
    seq_params->order_hint_info.enable_ref_frame_mvs = 0;
6013
19.7k
    seq_params->order_hint_info.order_hint_bits_minus_1 = -1;
6014
19.7k
  } else {
6015
2.00k
    int seq_enabled_motion_modes = (1 << SIMPLE_TRANSLATION);
6016
2.00k
    uint8_t motion_mode_enabled = 0;
6017
2.00k
    uint8_t warp_delta_enabled = 0;
6018
10.0k
    for (int motion_mode = INTERINTRA; motion_mode < MOTION_MODES;
6019
8.03k
         motion_mode++) {
6020
8.03k
      int enabled = avm_rb_read_bit(rb);
6021
8.03k
      motion_mode_enabled |= enabled;
6022
8.03k
      if (motion_mode == WARP_DELTA && enabled) {
6023
124
        warp_delta_enabled = 1;
6024
124
      }
6025
8.03k
      if (enabled) {
6026
3.31k
        seq_enabled_motion_modes |= (1 << motion_mode);
6027
3.31k
      }
6028
8.03k
    }
6029
2.00k
    seq_params->seq_frame_motion_modes_present_flag =
6030
2.00k
        motion_mode_enabled ? avm_rb_read_bit(rb) : 0;
6031
2.00k
    seq_params->enable_six_param_warp_delta =
6032
2.00k
        warp_delta_enabled ? avm_rb_read_bit(rb) : 0;
6033
2.00k
    seq_params->seq_enabled_motion_modes = seq_enabled_motion_modes;
6034
2.00k
    seq_params->enable_masked_compound = avm_rb_read_bit(rb);
6035
2.00k
    seq_params->order_hint_info.enable_ref_frame_mvs = avm_rb_read_bit(rb);
6036
2.00k
    seq_params->order_hint_info.reduced_ref_frame_mvs_mode =
6037
2.00k
        seq_params->order_hint_info.enable_ref_frame_mvs ? avm_rb_read_bit(rb)
6038
2.00k
                                                         : 0;
6039
6040
2.00k
    seq_params->order_hint_info.order_hint_bits_minus_1 =
6041
2.00k
        avm_rb_read_literal(rb, 4);
6042
2.00k
  }
6043
21.7k
  seq_params->enable_refmvbank = avm_rb_read_bit(rb);
6044
21.7k
  if (avm_rb_read_bit(rb)) {
6045
3.83k
    seq_params->enable_drl_reorder = DRL_REORDER_DISABLED;
6046
17.9k
  } else {
6047
17.9k
    seq_params->enable_drl_reorder =
6048
17.9k
        avm_rb_read_bit(rb) ? DRL_REORDER_CONSTRAINT : DRL_REORDER_ALWAYS;
6049
17.9k
  }
6050
21.7k
  if (seq_params->single_picture_header_flag) {
6051
19.7k
    seq_params->enable_explicit_ref_frame_map = 0;
6052
19.7k
    seq_params->ref_frames = 2;
6053
19.7k
    seq_params->ref_frames_log2 = 1;
6054
19.7k
    seq_params->number_of_bits_for_lt_frame_id = 0;
6055
19.7k
    seq_params->def_max_drl_bits = MIN_MAX_DRL_BITS;
6056
19.7k
    seq_params->allow_frame_max_drl_bits = 0;
6057
19.7k
  } else {
6058
2.01k
    seq_params->enable_explicit_ref_frame_map = avm_rb_read_bit(rb);
6059
2.01k
    if (avm_rb_read_bit(rb)) {
6060
289
      seq_params->ref_frames =
6061
289
          avm_rb_read_literal(rb, 4) + 1;  // explicitly signaled DPB size
6062
1.72k
    } else {
6063
1.72k
      seq_params->ref_frames = 8;  // default DPB size: 8
6064
1.72k
    }
6065
2.01k
    seq_params->ref_frames_log2 = avm_ceil_log2(seq_params->ref_frames);
6066
2.01k
    seq_params->number_of_bits_for_lt_frame_id = avm_rb_read_literal(rb, 3);
6067
2.01k
    seq_params->def_max_drl_bits =
6068
2.01k
        avm_rb_read_primitive_quniform(
6069
2.01k
            rb, MAX_MAX_DRL_BITS - MIN_MAX_DRL_BITS + 1) +
6070
2.01k
        MIN_MAX_DRL_BITS;
6071
2.01k
    seq_params->allow_frame_max_drl_bits = avm_rb_read_bit(rb);
6072
2.01k
  }
6073
21.7k
  seq_params->def_max_bvp_drl_bits =
6074
21.7k
      avm_rb_read_primitive_quniform(
6075
21.7k
          rb, MAX_MAX_IBC_DRL_BITS - MIN_MAX_IBC_DRL_BITS + 1) +
6076
21.7k
      MIN_MAX_IBC_DRL_BITS;
6077
21.7k
  seq_params->allow_frame_max_bvp_drl_bits = avm_rb_read_bit(rb);
6078
6079
21.7k
  seq_params->num_same_ref_compound =
6080
21.7k
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_literal(rb, 2);
6081
6082
21.7k
  uint8_t enable_tip =
6083
21.7k
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
6084
21.7k
  if (enable_tip) {
6085
870
    seq_params->enable_tip = 1 + avm_rb_read_bit(rb);
6086
20.8k
  } else {
6087
20.8k
    seq_params->enable_tip = 0;
6088
20.8k
  }
6089
21.7k
  if (seq_params->enable_tip) {
6090
870
    seq_params->enable_tip_hole_fill = avm_rb_read_bit(rb);
6091
20.8k
  } else {
6092
20.8k
    seq_params->enable_tip_hole_fill = 0;
6093
20.8k
  }
6094
21.7k
  seq_params->enable_mv_traj =
6095
21.7k
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
6096
21.7k
  seq_params->enable_bawp = avm_rb_read_bit(rb);
6097
21.7k
  seq_params->enable_cwp =
6098
21.7k
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
6099
21.7k
  seq_params->enable_imp_msk_bld =
6100
21.7k
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
6101
21.7k
  seq_params->enable_lf_sub_pu =
6102
21.7k
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
6103
21.7k
  if (seq_params->enable_tip == 1 && seq_params->enable_lf_sub_pu) {
6104
54
    seq_params->enable_tip_explicit_qp = avm_rb_read_bit(rb);
6105
21.7k
  } else {
6106
21.7k
    seq_params->enable_tip_explicit_qp = 0;
6107
21.7k
  }
6108
21.7k
  if (seq_params->single_picture_header_flag) {
6109
19.7k
    seq_params->enable_opfl_refine = AVM_OPFL_REFINE_NONE;
6110
19.7k
    seq_params->enable_refinemv = 0;
6111
19.7k
  } else {
6112
2.01k
    seq_params->enable_opfl_refine = avm_rb_read_literal(rb, 2);
6113
2.01k
    seq_params->enable_refinemv = avm_rb_read_bit(rb);
6114
2.01k
  }
6115
6116
21.7k
  seq_params->enable_tip_refinemv =
6117
21.7k
      (seq_params->enable_tip &&
6118
870
       (seq_params->enable_opfl_refine || seq_params->enable_refinemv))
6119
21.7k
          ? avm_rb_read_bit(rb)
6120
21.7k
          : 0;
6121
6122
21.7k
  if (seq_params->single_picture_header_flag) {
6123
19.7k
    seq_params->enable_bru = 0;
6124
19.7k
    seq_params->enable_adaptive_mvd = 0;
6125
19.7k
    seq_params->enable_mvd_sign_derive = 0;
6126
19.7k
    seq_params->enable_flex_mvres = 0;
6127
19.7k
  } else {
6128
2.01k
    seq_params->enable_bru = avm_rb_read_bit(rb);
6129
2.01k
    seq_params->enable_adaptive_mvd = avm_rb_read_bit(rb);
6130
2.01k
    seq_params->enable_mvd_sign_derive = avm_rb_read_bit(rb);
6131
2.01k
    seq_params->enable_flex_mvres = avm_rb_read_bit(rb);
6132
2.01k
  }
6133
21.7k
  if (seq_params->single_picture_header_flag) {
6134
19.7k
    seq_params->enable_global_motion = 0;
6135
19.7k
  } else {
6136
2.01k
    seq_params->enable_global_motion = avm_rb_read_bit(rb);
6137
2.01k
  }
6138
6139
21.7k
  if (seq_params->single_picture_header_flag) {
6140
19.7k
    seq_params->enable_short_refresh_frame_flags = 0;
6141
19.7k
  } else {
6142
2.01k
    seq_params->enable_short_refresh_frame_flags = avm_rb_read_bit(rb);
6143
2.01k
  }
6144
21.7k
}
6145
6146
void read_sequence_scc_group_tool_flags(struct SequenceHeader *seq_params,
6147
21.7k
                                        struct avm_read_bit_buffer *rb) {
6148
21.7k
  if (seq_params->single_picture_header_flag) {
6149
19.7k
    seq_params->force_screen_content_tools = 2;  // SELECT_SCREEN_CONTENT_TOOLS
6150
19.7k
    seq_params->force_integer_mv = 2;            // SELECT_INTEGER_MV
6151
19.7k
  } else {
6152
2.00k
    if (avm_rb_read_bit(rb)) {
6153
130
      seq_params->force_screen_content_tools =
6154
130
          2;  // SELECT_SCREEN_CONTENT_TOOLS
6155
1.87k
    } else {
6156
1.87k
      seq_params->force_screen_content_tools = avm_rb_read_bit(rb);
6157
1.87k
    }
6158
6159
2.00k
    if (seq_params->force_screen_content_tools > 0) {
6160
583
      if (avm_rb_read_bit(rb)) {
6161
126
        seq_params->force_integer_mv = 2;  // SELECT_INTEGER_MV
6162
457
      } else {
6163
457
        seq_params->force_integer_mv = avm_rb_read_bit(rb);
6164
457
      }
6165
1.42k
    } else {
6166
1.42k
      seq_params->force_integer_mv = 2;  // SELECT_INTEGER_MV
6167
1.42k
    }
6168
2.00k
  }
6169
21.7k
}
6170
6171
void read_sequence_filter_group_tool_flags(struct SequenceHeader *seq_params,
6172
21.7k
                                           struct avm_read_bit_buffer *rb) {
6173
21.7k
  seq_params->disable_loopfilters_across_tiles = avm_rb_read_bit(rb);
6174
21.7k
  seq_params->enable_cdef = avm_rb_read_bit(rb);
6175
21.7k
  seq_params->enable_gdf = avm_rb_read_bit(rb);
6176
21.7k
  if (seq_params->enable_gdf && seq_params->sb_size != BLOCK_256X256 &&
6177
17.4k
      seq_params->sb_size != BLOCK_128X128) {
6178
16.0k
    seq_params->gdf_unit_matches_sb_size = avm_rb_read_bit(rb);
6179
16.0k
  } else {
6180
5.74k
    seq_params->gdf_unit_matches_sb_size = 0;
6181
5.74k
  }
6182
21.7k
  seq_params->enable_restoration = avm_rb_read_bit(rb);
6183
21.7k
  seq_params->lr_tools_disable_mask[0] = 0;
6184
21.7k
  seq_params->lr_tools_disable_mask[1] = 0;
6185
21.7k
  if (seq_params->enable_restoration) {
6186
59.0k
    for (int i = 1; i < RESTORE_SWITCHABLE_TYPES; ++i) {
6187
39.3k
      seq_params->lr_tools_disable_mask[0] |= (avm_rb_read_bit(rb) << i);
6188
39.3k
    }
6189
19.6k
    if (avm_rb_read_bit(rb)) {
6190
4.78k
      seq_params->lr_tools_disable_mask[1] = DEF_UV_LR_TOOLS_DISABLE_MASK;
6191
14.3k
      for (int i = 1; i < RESTORE_SWITCHABLE_TYPES; ++i) {
6192
9.56k
        if (DEF_UV_LR_TOOLS_DISABLE_MASK & (1 << i)) continue;
6193
4.78k
        seq_params->lr_tools_disable_mask[1] |= (avm_rb_read_bit(rb) << i);
6194
4.78k
      }
6195
14.8k
    } else {
6196
14.8k
      seq_params->lr_tools_disable_mask[1] =
6197
14.8k
          (seq_params->lr_tools_disable_mask[0] | DEF_UV_LR_TOOLS_DISABLE_MASK);
6198
14.8k
    }
6199
19.6k
  }
6200
21.7k
  seq_params->enable_ccso = avm_rb_read_bit(rb);
6201
21.7k
  if (seq_params->enable_ccso) {
6202
19.5k
    seq_params->ccso_unit_matches_sb_size = avm_rb_read_bit(rb);
6203
19.5k
  } else {
6204
2.20k
    seq_params->ccso_unit_matches_sb_size = 0;
6205
2.20k
  }
6206
21.7k
  if (seq_params->single_picture_header_flag) {
6207
19.7k
    seq_params->enable_cdef_on_skip_txfm = CDEF_ON_SKIP_TXFM_ADAPTIVE;
6208
19.7k
  } else {
6209
1.99k
    if (avm_rb_read_bit(rb)) {
6210
570
      seq_params->enable_cdef_on_skip_txfm = CDEF_ON_SKIP_TXFM_ALWAYS_ON;
6211
1.42k
    } else {
6212
1.42k
      seq_params->enable_cdef_on_skip_txfm = avm_rb_read_bit(rb)
6213
1.42k
                                                 ? CDEF_ON_SKIP_TXFM_DISABLED
6214
1.42k
                                                 : CDEF_ON_SKIP_TXFM_ADAPTIVE;
6215
1.42k
    }
6216
1.99k
  }
6217
21.7k
  seq_params->df_par_bits_minus2 = avm_rb_read_literal(rb, 2);
6218
21.7k
}
6219
6220
void read_sequence_transform_quant_entropy_group_tool_flags(
6221
21.7k
    struct SequenceHeader *seq_params, struct avm_read_bit_buffer *rb) {
6222
21.7k
  seq_params->enable_fsc = avm_rb_read_bit(rb);
6223
21.7k
  if (!seq_params->enable_fsc) {
6224
19.3k
    seq_params->enable_idtx_intra = avm_rb_read_bit(rb);
6225
19.3k
  } else {
6226
2.45k
    seq_params->enable_idtx_intra = 1;
6227
2.45k
  }
6228
21.7k
  seq_params->enable_ist = avm_rb_read_bit(rb);
6229
21.7k
  seq_params->enable_inter_ist = avm_rb_read_bit(rb);
6230
21.7k
  seq_params->enable_chroma_dctonly =
6231
21.7k
      seq_params->monochrome ? 0 : avm_rb_read_bit(rb);
6232
21.7k
  seq_params->enable_inter_ddt =
6233
21.7k
      seq_params->single_picture_header_flag ? 0 : avm_rb_read_bit(rb);
6234
21.7k
  seq_params->reduced_tx_part_set = avm_rb_read_bit(rb);
6235
21.7k
  seq_params->enable_cctx = seq_params->monochrome ? 0 : avm_rb_read_bit(rb);
6236
21.7k
  seq_params->enable_tcq = 0;
6237
21.7k
  int enable_tcq = avm_rb_read_bit(rb);
6238
21.7k
  if (enable_tcq) {
6239
18.0k
    if (!seq_params->single_picture_header_flag)
6240
587
      enable_tcq += avm_rb_read_bit(rb);
6241
18.0k
    seq_params->enable_tcq = enable_tcq;
6242
18.0k
  }
6243
6244
21.7k
  if (seq_params->enable_tcq == TCQ_DISABLE ||
6245
18.0k
      seq_params->enable_tcq >= TCQ_8ST_FR) {
6246
4.33k
    seq_params->enable_parity_hiding = avm_rb_read_bit(rb);
6247
17.4k
  } else {
6248
17.4k
    seq_params->enable_parity_hiding = 0;
6249
17.4k
  }
6250
6251
21.7k
  if (seq_params->single_picture_header_flag) {
6252
    // Setting both enable_avg_cdf and avg_cdf_type to 1 allows us to omit the
6253
    // context_update_tile_id syntax element in tile_info(), which is part of
6254
    // uncompressed_header().
6255
19.7k
    seq_params->enable_avg_cdf = 1;
6256
19.7k
    seq_params->avg_cdf_type = 1;
6257
19.7k
  } else {
6258
2.01k
    seq_params->enable_avg_cdf = avm_rb_read_bit(rb);
6259
2.01k
    if (seq_params->enable_avg_cdf) {
6260
571
      seq_params->avg_cdf_type = avm_rb_read_bit(rb);
6261
571
    }
6262
2.01k
  }
6263
21.7k
  const int is_monochrome = seq_params->monochrome;
6264
21.7k
  if (is_monochrome) {
6265
2.40k
    seq_params->separate_uv_delta_q = 0;
6266
19.3k
  } else {
6267
19.3k
    seq_params->separate_uv_delta_q = avm_rb_read_bit(rb);
6268
19.3k
  }
6269
6270
21.7k
  seq_params->equal_ac_dc_q = avm_rb_read_bit(rb);
6271
21.7k
  if (!seq_params->equal_ac_dc_q) {
6272
1.41k
    seq_params->base_y_dc_delta_q =
6273
1.41k
        DELTA_DCQUANT_MIN + avm_rb_read_literal(rb, DELTA_DCQUANT_BITS);
6274
1.41k
    seq_params->y_dc_delta_q_enabled = avm_rb_read_bit(rb);
6275
20.3k
  } else {
6276
20.3k
    seq_params->base_y_dc_delta_q = 0;
6277
20.3k
    seq_params->y_dc_delta_q_enabled = 0;
6278
20.3k
  }
6279
21.7k
  if (!is_monochrome) {
6280
19.3k
    if (!seq_params->equal_ac_dc_q) {
6281
519
      seq_params->base_uv_dc_delta_q =
6282
519
          DELTA_DCQUANT_MIN + avm_rb_read_literal(rb, DELTA_DCQUANT_BITS);
6283
519
      seq_params->uv_dc_delta_q_enabled = avm_rb_read_bit(rb);
6284
18.8k
    } else {
6285
18.8k
      seq_params->uv_dc_delta_q_enabled = 0;
6286
18.8k
    }
6287
19.3k
    seq_params->base_uv_ac_delta_q =
6288
19.3k
        DELTA_DCQUANT_MIN + avm_rb_read_literal(rb, DELTA_DCQUANT_BITS);
6289
19.3k
    seq_params->uv_ac_delta_q_enabled = avm_rb_read_bit(rb);
6290
19.3k
    if (seq_params->equal_ac_dc_q)
6291
18.8k
      seq_params->base_uv_dc_delta_q = seq_params->base_uv_ac_delta_q;
6292
19.3k
  } else {
6293
2.42k
    seq_params->base_uv_dc_delta_q = 0;
6294
2.42k
    seq_params->base_uv_ac_delta_q = 0;
6295
2.42k
    seq_params->uv_dc_delta_q_enabled = 0;
6296
2.42k
    seq_params->uv_ac_delta_q_enabled = 0;
6297
2.42k
  }
6298
21.7k
}
6299
6300
void read_sequence_segment_tool_flags(struct SequenceHeader *seq_params,
6301
21.9k
                                      struct avm_read_bit_buffer *rb) {
6302
21.9k
  seq_params->enable_ext_seg = avm_rb_read_bit(rb);
6303
21.9k
  seq_params->seq_seg_info_present_flag = avm_rb_read_bit(rb);
6304
21.9k
  if (seq_params->seq_seg_info_present_flag) {
6305
1.05k
    seq_params->seg_params.enable_ext_seg = seq_params->enable_ext_seg;
6306
1.05k
    read_seg_syntax_info(&seq_params->seg_params, rb);
6307
1.05k
  }
6308
21.9k
}
6309
6310
void av2_read_sequence_header(struct avm_read_bit_buffer *rb,
6311
21.9k
                              SequenceHeader *seq_params) {
6312
21.9k
  seq_params->seq_tile_info_present_flag = 0;
6313
21.9k
  seq_params->tile_params.allow_tile_info_change = 0;
6314
21.9k
  read_sequence_partition_group_tool_flags(seq_params, rb);
6315
21.9k
  read_sequence_segment_tool_flags(seq_params, rb);
6316
21.9k
  read_sequence_intra_group_tool_flags(seq_params, rb);
6317
21.9k
  read_sequence_inter_group_tool_flags(seq_params, rb);
6318
21.9k
  read_sequence_scc_group_tool_flags(seq_params, rb);
6319
21.9k
  read_sequence_transform_quant_entropy_group_tool_flags(seq_params, rb);
6320
21.9k
  read_sequence_filter_group_tool_flags(seq_params, rb);
6321
21.9k
  read_sequence_tile_config(seq_params, rb);
6322
21.9k
}
6323
6324
static AVM_INLINE void read_multi_frame_header_seg_info(
6325
2
    MultiFrameHeader *mfh_param, struct avm_read_bit_buffer *rb) {
6326
2
  mfh_param->mfh_seg_info_present_flag = avm_rb_read_bit(rb);
6327
2
  if (mfh_param->mfh_seg_info_present_flag) {
6328
0
    mfh_param->mfh_ext_seg_flag = avm_rb_read_bit(rb);
6329
0
    mfh_param->mfh_seg_params.enable_ext_seg = mfh_param->mfh_ext_seg_flag;
6330
0
    read_seg_syntax_info(&mfh_param->mfh_seg_params, rb);
6331
0
  }
6332
2
}
6333
6334
uint32_t av2_read_multi_frame_header(AV2_COMMON *cm,
6335
6
                                     struct avm_read_bit_buffer *rb) {
6336
6
  const uint32_t mfh_seq_header_id = avm_rb_read_uvlc(rb);
6337
6
  if (mfh_seq_header_id >= MAX_SEQ_NUM) {
6338
4
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
6339
4
                       "Unsupported Sequence Header ID in MFH");
6340
4
  }
6341
6
  const uint32_t mfh_id_minus_1 = avm_rb_read_uvlc(rb);
6342
6
  if (mfh_id_minus_1 >= MAX_MFH_NUM - 1) {
6343
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
6344
0
                       "multi-frame header id is greater than or equal to the "
6345
0
                       "maximum multi-frame header number");
6346
0
  }
6347
6
  const uint32_t cur_mfh_id = mfh_id_minus_1 + 1;
6348
6349
6
  MultiFrameHeader *mfh_param = &cm->mfh_params[cur_mfh_id];
6350
6
  mfh_param->mfh_seq_header_id = (int)mfh_seq_header_id;
6351
6
  mfh_param->mfh_mlayer_id = cm->mlayer_id;
6352
6
  mfh_param->mfh_tlayer_id = cm->tlayer_id;
6353
6
  mfh_param->mfh_frame_width = cm->seq_params.max_frame_width;
6354
6
  mfh_param->mfh_frame_height = cm->seq_params.max_frame_height;
6355
6
  mfh_param->mfh_frame_size_present_flag = avm_rb_read_bit(rb);
6356
6
  if (mfh_param->mfh_frame_size_present_flag) {
6357
2
    mfh_param->mfh_frame_width_bits_minus1 = avm_rb_read_literal(rb, 4);
6358
2
    int num_bits_width = mfh_param->mfh_frame_width_bits_minus1 + 1;
6359
2
    mfh_param->mfh_frame_height_bits_minus1 = avm_rb_read_literal(rb, 4);
6360
2
    int num_bits_height = mfh_param->mfh_frame_height_bits_minus1 + 1;
6361
2
    av2_read_frame_size(rb, num_bits_width, num_bits_height,
6362
2
                        &mfh_param->mfh_frame_width,
6363
2
                        &mfh_param->mfh_frame_height);
6364
2
  }
6365
6
  mfh_param->mfh_deblocking_filter_update_flag = avm_rb_read_bit(rb);
6366
6
  if (mfh_param->mfh_deblocking_filter_update_flag) {
6367
10
    for (int i = 0; i < 4; i++) {
6368
8
      mfh_param->mfh_apply_deblocking_filter[i] = avm_rb_read_bit(rb);
6369
8
    }
6370
4
  } else {
6371
4
    for (int i = 0; i < 4; i++) {
6372
0
      mfh_param->mfh_apply_deblocking_filter[i] = 0;
6373
0
    }
6374
4
  }
6375
6376
6
  read_multi_frame_header_seg_info(mfh_param, rb);
6377
6378
6
  cm->mfh_valid[cur_mfh_id] = true;
6379
6
  return cur_mfh_id;
6380
6
}
6381
6382
static void read_global_motion_params(WarpedMotionParams *params,
6383
                                      const WarpedMotionParams *ref_params,
6384
                                      struct avm_read_bit_buffer *rb,
6385
6386
                                      const struct scale_factors *sf,
6387
6388
0
                                      MvSubpelPrecision precision) {
6389
0
  const int precision_loss = get_gm_precision_loss(precision);
6390
0
  (void)precision_loss;
6391
0
  TransformationType type = avm_rb_read_bit(rb);
6392
0
  if (type != IDENTITY) {
6393
0
    if (avm_rb_read_bit(rb)) {
6394
0
      type = ROTZOOM;
6395
0
    } else {
6396
0
      type = AFFINE;
6397
0
    }
6398
0
  }
6399
6400
0
  *params = default_warp_params;
6401
0
  params->wmtype = type;
6402
6403
0
  if (type >= ROTZOOM) {
6404
0
    params->wmmat[2] = avm_rb_read_signed_primitive_refsubexpfin(
6405
0
                           rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
6406
0
                           (ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) -
6407
0
                               (1 << GM_ALPHA_PREC_BITS)) *
6408
0
                           GM_ALPHA_DECODE_FACTOR +
6409
0
                       (1 << WARPEDMODEL_PREC_BITS);
6410
0
    params->wmmat[3] = avm_rb_read_signed_primitive_refsubexpfin(
6411
0
                           rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
6412
0
                           (ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF)) *
6413
0
                       GM_ALPHA_DECODE_FACTOR;
6414
0
  }
6415
6416
0
  if (type >= AFFINE) {
6417
0
    params->wmmat[4] = avm_rb_read_signed_primitive_refsubexpfin(
6418
0
                           rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
6419
0
                           (ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF)) *
6420
0
                       GM_ALPHA_DECODE_FACTOR;
6421
0
    params->wmmat[5] = avm_rb_read_signed_primitive_refsubexpfin(
6422
0
                           rb, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
6423
0
                           (ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
6424
0
                               (1 << GM_ALPHA_PREC_BITS)) *
6425
0
                           GM_ALPHA_DECODE_FACTOR +
6426
0
                       (1 << WARPEDMODEL_PREC_BITS);
6427
0
  } else {
6428
0
    params->wmmat[4] = -params->wmmat[3];
6429
0
    params->wmmat[5] = params->wmmat[2];
6430
0
  }
6431
6432
0
  if (type >= TRANSLATION) {
6433
0
    const int trans_dec_factor = GM_TRANS_DECODE_FACTOR;
6434
0
    const int trans_prec_diff = GM_TRANS_PREC_DIFF;
6435
0
    const int trans_max = GM_TRANS_MAX;
6436
6437
0
    params->wmmat[0] = avm_rb_read_signed_primitive_refsubexpfin(
6438
0
                           rb, trans_max + 1, SUBEXPFIN_K,
6439
0
                           (ref_params->wmmat[0] >> trans_prec_diff)) *
6440
0
                       trans_dec_factor;
6441
0
    params->wmmat[1] = avm_rb_read_signed_primitive_refsubexpfin(
6442
0
                           rb, trans_max + 1, SUBEXPFIN_K,
6443
0
                           (ref_params->wmmat[1] >> trans_prec_diff)) *
6444
0
                       trans_dec_factor;
6445
0
  }
6446
6447
0
  if (params->wmtype <= AFFINE) {
6448
0
    av2_reduce_warp_model(params);
6449
0
    av2_get_shear_params(params, sf);
6450
0
  }
6451
0
}
6452
6453
static AVM_INLINE void read_global_motion(AV2_COMMON *cm,
6454
0
                                          struct avm_read_bit_buffer *rb) {
6455
0
  const SequenceHeader *const seq_params = &cm->seq_params;
6456
0
  int num_total_refs = cm->ref_frames_info.num_total_refs;
6457
0
  bool use_global_motion = false;
6458
0
  if (seq_params->enable_global_motion) {
6459
0
    use_global_motion = avm_rb_read_bit(rb);
6460
0
  }
6461
0
  if (!use_global_motion) {
6462
0
    for (int frame = 0; frame < INTER_REFS_PER_FRAME; ++frame) {
6463
0
      cm->global_motion[frame] = default_warp_params;
6464
0
      cm->cur_frame->global_motion[frame] = default_warp_params;
6465
0
    }
6466
0
    return;
6467
0
  }
6468
6469
0
  int our_ref = num_total_refs;
6470
0
  if (!frame_is_sframe(cm))
6471
0
    our_ref = avm_rb_read_primitive_quniform(rb, num_total_refs + 1);
6472
0
  if (our_ref == num_total_refs) {
6473
    // Special case: Use IDENTITY model
6474
0
    cm->base_global_motion_model = default_warp_params;
6475
0
    cm->base_global_motion_distance = 1;
6476
0
  } else {
6477
0
    RefCntBuffer *buf = get_ref_frame_buf(cm, our_ref);
6478
0
    assert(buf);
6479
0
    if (buf->is_restricted) {
6480
0
      avm_internal_error(&cm->error, AVM_CODEC_ERROR,
6481
0
                         "Invalid our_ref: restricted reference buffer");
6482
0
    }
6483
0
    int their_num_refs = buf->num_ref_frames;
6484
0
    if (their_num_refs == 0) {
6485
      // Special case: if an intra/key frame is used as a ref, use an
6486
      // IDENTITY model
6487
0
      cm->base_global_motion_model = default_warp_params;
6488
0
      cm->base_global_motion_distance = 1;
6489
0
    } else {
6490
0
      const int their_ref = avm_rb_read_primitive_quniform(rb, their_num_refs);
6491
0
      if (buf->refs_restricted_status[their_ref]) {
6492
0
        avm_internal_error(&cm->error, AVM_CODEC_ERROR,
6493
0
                           "Invalid their_ref: restricted reference buffer");
6494
0
      }
6495
0
      const int our_ref_order_hint = buf->display_order_hint;
6496
0
      const int their_ref_order_hint = buf->ref_display_order_hint[their_ref];
6497
0
      cm->base_global_motion_model = buf->global_motion[their_ref];
6498
0
      cm->base_global_motion_distance =
6499
0
          get_relative_dist(&seq_params->order_hint_info, our_ref_order_hint,
6500
0
                            their_ref_order_hint);
6501
0
    }
6502
0
  }
6503
6504
0
  for (int frame = 0; frame < cm->ref_frames_info.num_total_refs; ++frame) {
6505
0
    int temporal_distance;
6506
0
    const RefCntBuffer *const ref_buf = get_ref_frame_buf(cm, frame);
6507
0
    if (ref_buf->is_restricted) {
6508
0
      cm->global_motion[frame].invalid = 1;
6509
0
      continue;
6510
0
    }
6511
0
    const int ref_order_hint = ref_buf->display_order_hint;
6512
0
    const int cur_order_hint = cm->cur_frame->display_order_hint;
6513
0
    temporal_distance = get_relative_dist(&seq_params->order_hint_info,
6514
0
                                          cur_order_hint, ref_order_hint);
6515
6516
0
    if (temporal_distance == 0) {
6517
      // Don't code global motion for frames at the same temporal instant
6518
0
      cm->global_motion[frame] = default_warp_params;
6519
0
      continue;
6520
0
    }
6521
6522
0
    WarpedMotionParams ref_params_;
6523
0
    av2_scale_warp_model(&cm->base_global_motion_model,
6524
0
                         cm->base_global_motion_distance, &ref_params_,
6525
0
                         temporal_distance);
6526
0
    WarpedMotionParams *ref_params = &ref_params_;
6527
0
    read_global_motion_params(&cm->global_motion[frame], ref_params, rb,
6528
6529
0
                              get_ref_scale_factors_const(cm, frame),
6530
6531
0
                              cm->features.fr_mv_precision);
6532
6533
    // TODO(sarahparker, debargha): The logic in the commented out code below
6534
    // does not work currently and causes mismatches when resize is on. Fix it
6535
    // before turning the optimization back on.
6536
    /*
6537
    YV12_BUFFER_CONFIG *ref_buf = get_ref_frame(cm, frame);
6538
    if (cm->width == ref_buf->y_crop_width &&
6539
        cm->height == ref_buf->y_crop_height) {
6540
      read_global_motion_params(&cm->global_motion[frame],
6541
                                &cm->prev_frame->global_motion[frame], rb,
6542
                                cm->features.allow_high_precision_mv);
6543
    } else {
6544
      cm->global_motion[frame] = default_warp_params;
6545
    }
6546
    */
6547
    /*
6548
    printf("Dec Ref %d [%d/%d]: %d %d %d %d\n",
6549
           frame, cm->current_frame.frame_number, cm->immediate_output_picture,
6550
           cm->global_motion[frame].wmmat[0],
6551
           cm->global_motion[frame].wmmat[1],
6552
           cm->global_motion[frame].wmmat[2],
6553
           cm->global_motion[frame].wmmat[3]);
6554
           */
6555
0
  }
6556
0
  memcpy(cm->cur_frame->global_motion, cm->global_motion,
6557
0
         INTER_REFS_PER_FRAME * sizeof(WarpedMotionParams));
6558
0
}
6559
6560
// Release the references to the frame buffers in cm->ref_frame_map and reset
6561
// all elements of cm->ref_frame_map to NULL.
6562
19.3k
static AVM_INLINE void reset_ref_frame_map(AV2_COMMON *const cm) {
6563
19.3k
  BufferPool *const pool = cm->buffer_pool;
6564
57.9k
  for (int i = 0; i < cm->seq_params.ref_frames; i++) {
6565
38.5k
    decrease_ref_count(cm->ref_frame_map[i], pool);
6566
38.5k
    cm->ref_frame_map[i] = NULL;
6567
38.5k
  }
6568
19.3k
}
6569
6570
// If the refresh_frame_flags bitmask is set, update reference frame id values
6571
// and mark frames as valid for reference.
6572
16.3k
static AVM_INLINE void validate_references(AV2Decoder *const pbi) {
6573
16.3k
  AV2_COMMON *const cm = &pbi->common;
6574
16.3k
  const int refresh_frame_flags = cm->current_frame.refresh_frame_flags;
6575
16.3k
  int first_ref_index;
6576
16.3k
  const bool clear_multiple_insert_in_one =
6577
16.3k
      av2_frame_clears_multiple_inserted_in_one(
6578
16.3k
          refresh_frame_flags, cm->current_frame.frame_type, &first_ref_index);
6579
6580
48.9k
  for (int i = 0; i < cm->seq_params.ref_frames; i++) {
6581
32.5k
    if ((refresh_frame_flags >> i) & 1) {
6582
32.5k
      if (av2_skip_reference_buffer_update(clear_multiple_insert_in_one, i,
6583
32.5k
                                           first_ref_index)) {
6584
16.2k
        pbi->valid_for_referencing[i] = 0;
6585
16.2k
      } else {
6586
16.2k
        pbi->valid_for_referencing[i] = 1;
6587
16.2k
      }
6588
32.5k
    }
6589
32.5k
  }
6590
16.3k
}
6591
6592
16.4k
static INLINE void reset_frame_buffers(AV2_COMMON *cm) {
6593
16.4k
  RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
6594
16.4k
  int i;
6595
6596
16.4k
  lock_buffer_pool(cm->buffer_pool);
6597
16.4k
  assert(cm->cur_frame->ref_count == 1);
6598
12.6M
  for (i = 0; i < FRAME_BUFFERS; ++i) {
6599
    // Reset all unreferenced frame buffers. We can also reset cm->cur_frame
6600
    // because we are the sole owner of cm->cur_frame.
6601
12.6M
    if (frame_bufs[i].ref_count > 0 && &frame_bufs[i] != cm->cur_frame) {
6602
0
      continue;
6603
0
    }
6604
12.6M
    frame_bufs[i].order_hint = 0;
6605
12.6M
    frame_bufs[i].display_order_hint = 0;
6606
12.6M
    av2_zero(frame_bufs[i].ref_display_order_hint);
6607
12.6M
    av2_zero(frame_bufs[i].ref_order_hints);
6608
12.6M
  }
6609
16.4k
  av2_zero_unused_internal_frame_buffers(&cm->buffer_pool->int_frame_buffers);
6610
16.4k
  unlock_buffer_pool(cm->buffer_pool);
6611
16.4k
}
6612
6613
// This function is used to dervie DOH to check the first keyobu of the temporal
6614
// unit. This function must be updated with the get_disp_order_hint()
6615
int get_disp_order_hint_keyobu(SequenceHeader *seq_params, OBU_TYPE obu_type,
6616
                               int order_hint, int tlayer_id, int mlayer_id,
6617
                               RefCntBuffer **ref_frame_map,
6618
                               bool random_accessed, bool is_op_constrained,
6619
0
                               const int mlayer_mask, const int tlayer_mask) {
6620
0
  if (is_op_constrained) {
6621
    // This configuration is only used for conformance checking in the AVM
6622
    // reference software.
6623
0
    assert(mlayer_mask >= 0 && mlayer_mask < (1 << MAX_NUM_MLAYERS));
6624
0
    assert(tlayer_mask >= 0 && tlayer_mask < (1 << MAX_NUM_TLAYERS));
6625
0
  } else {
6626
    // This configuration is used in actual decoding process. Thus,
6627
    // op_max_mlayer_id and op_max_tlayer_id are not needed and should be set to
6628
    // -1 if is_op_constrained is false.
6629
0
    assert(mlayer_mask == -1 && mlayer_mask == -1);
6630
0
  }
6631
6632
0
  if (obu_type == OBU_CLOSED_LOOP_KEY) {
6633
0
    return order_hint;
6634
0
  } else if (obu_type == OBU_OPEN_LOOP_KEY) {
6635
0
    if (random_accessed) return order_hint;
6636
0
  }
6637
6638
  // Derive the exact display order hint from the signaled order_hint.
6639
  // This requires scaling up order_hints corresponding to frame
6640
  // numbers that exceed the number of bits available to send the order_hints.
6641
6642
  // Find the reference frame with the largest order_hint
6643
0
  int max_disp_order_hint = 0;
6644
0
  for (int map_idx = 0; map_idx < seq_params->ref_frames; map_idx++) {
6645
    // Get reference frame buffer
6646
0
    const RefCntBuffer *const buf = ref_frame_map[map_idx];
6647
0
    if (buf == NULL ||
6648
0
        (!buf->implicit_output_picture && !buf->immediate_output_picture) ||
6649
0
        buf->is_restricted ||
6650
0
        !is_tlayer_scalable_and_dependent(seq_params, tlayer_id, buf->tlayer_id,
6651
0
                                          mlayer_id) ||
6652
0
        !is_mlayer_scalable_and_dependent(seq_params, mlayer_id,
6653
0
                                          buf->mlayer_id))
6654
0
      continue;
6655
    // Note: Exercising this condition is only used for the bitstream
6656
    // conformance check in the AVM reference software. Decoder implementations
6657
    // may skip this check since this conditional check shall not change the
6658
    // display order hint derivation.
6659
0
    if (is_op_constrained && (is_layer_dropped(buf->mlayer_id, mlayer_mask) ||
6660
0
                              is_layer_dropped(buf->tlayer_id, tlayer_mask)))
6661
0
      continue;
6662
6663
0
    if ((int)buf->display_order_hint > max_disp_order_hint)
6664
0
      max_disp_order_hint = buf->display_order_hint;
6665
0
  }
6666
6667
0
  int cur_disp_order_hint = order_hint;
6668
0
  int display_order_hint_factor =
6669
0
      1 << (seq_params->order_hint_info.order_hint_bits_minus_1 + 1);
6670
6671
0
  while (abs(max_disp_order_hint - cur_disp_order_hint) >=
6672
0
         (display_order_hint_factor >> 1)) {
6673
0
    if (cur_disp_order_hint > max_disp_order_hint) return cur_disp_order_hint;
6674
0
    cur_disp_order_hint += display_order_hint_factor;
6675
0
  }
6676
  // We restrict the derived display order hint to a range, to avoid 32 bit
6677
  // integer overflow and some corner cases when display order hint operations
6678
  // are performed in DISPLAY_ORDER_HINT_BITS bit range
6679
0
  struct avm_internal_error_info error_info;
6680
0
  error_info.error_code = AVM_CODEC_OK;
6681
0
  if (cur_disp_order_hint >= (1 << (DISPLAY_ORDER_HINT_BITS - 1)))
6682
0
    avm_internal_error(&error_info, AVM_CODEC_ERROR,
6683
0
                       "Derived display order hint is invalid");
6684
0
  return cur_disp_order_hint;
6685
0
}
6686
6687
static INLINE int get_disp_order_hint(AV2_COMMON *const cm, OBU_TYPE obu_type,
6688
                                      bool random_accessed,
6689
                                      bool is_op_constrained,
6690
                                      const int mlayer_mask,
6691
17
                                      const int tlayer_mask) {
6692
  // NOTE: when this function is updated, get_disp_order_hint_keyobu() must be
6693
  // updated.
6694
17
  if (is_op_constrained) {
6695
    // This configuration is only used for conformance checking in the AVM
6696
    // reference software.
6697
0
    assert(mlayer_mask >= 0 && mlayer_mask < (1 << MAX_NUM_MLAYERS));
6698
0
    assert(tlayer_mask >= 0 && tlayer_mask < (1 << MAX_NUM_TLAYERS));
6699
17
  } else {
6700
    // This configuration is used in actual decoding process. Thus,
6701
    // op_max_mlayer_id and op_max_tlayer_id are not needed and should be set to
6702
    // -1 if is_op_constrained is false.
6703
17
    assert(mlayer_mask == -1 && mlayer_mask == -1);
6704
17
  }
6705
17
  CurrentFrame *const current_frame = &cm->current_frame;
6706
17
  if (obu_type == OBU_CLOSED_LOOP_KEY) {
6707
16
    return current_frame->order_hint;
6708
16
  } else if (obu_type == OBU_OPEN_LOOP_KEY) {
6709
1
    if (random_accessed) return current_frame->order_hint;
6710
1
  }
6711
1
  if (current_frame->frame_type == S_FRAME &&
6712
0
      cm->restricted_prediction_switch && !cm->show_existing_frame) {
6713
0
    return current_frame->order_hint;
6714
0
  }
6715
  // Derive the exact display order hint from the signaled order_hint.
6716
  // This requires scaling up order_hints corresponding to frame
6717
  // numbers that exceed the number of bits available to send the order_hints.
6718
6719
  // Find the reference frame with the largest order_hint
6720
1
  int max_disp_order_hint = 0;
6721
1
  for (int map_idx = 0; map_idx < cm->seq_params.ref_frames; map_idx++) {
6722
    // Get reference frame buffer
6723
0
    const RefCntBuffer *const buf = cm->ref_frame_map[map_idx];
6724
0
    if (buf == NULL ||
6725
0
        (!buf->implicit_output_picture && !buf->immediate_output_picture) ||
6726
0
        buf->is_restricted ||
6727
0
        !is_tlayer_scalable_and_dependent(&cm->seq_params, cm->tlayer_id,
6728
0
                                          buf->tlayer_id, cm->mlayer_id) ||
6729
0
        !is_mlayer_scalable_and_dependent(&cm->seq_params, cm->mlayer_id,
6730
0
                                          buf->mlayer_id))
6731
0
      continue;
6732
    // Note: Exercising this condition is only used for the bitstream
6733
    // conformance check in the AVM reference software. Decoder implementations
6734
    // may skip this check since this conditional check shall not change the
6735
    // display order hint derivation.
6736
0
    if (is_op_constrained && (is_layer_dropped(buf->mlayer_id, mlayer_mask) ||
6737
0
                              is_layer_dropped(buf->tlayer_id, tlayer_mask)))
6738
0
      continue;
6739
6740
0
    if ((int)buf->display_order_hint > max_disp_order_hint)
6741
0
      max_disp_order_hint = buf->display_order_hint;
6742
0
  }
6743
6744
1
  int cur_disp_order_hint = current_frame->order_hint;
6745
1
  int display_order_hint_factor =
6746
1
      1 << (cm->seq_params.order_hint_info.order_hint_bits_minus_1 + 1);
6747
6748
1
  while (abs(max_disp_order_hint - cur_disp_order_hint) >=
6749
1
         (display_order_hint_factor >> 1)) {
6750
1
    if (cur_disp_order_hint > max_disp_order_hint) return cur_disp_order_hint;
6751
0
    cur_disp_order_hint += display_order_hint_factor;
6752
0
  }
6753
  // We restrict the derived display order hint to a range, to avoid 32 bit
6754
  // integer overflow and some corner cases when display order hint operations
6755
  // are performed in DISPLAY_ORDER_HINT_BITS bit range
6756
0
  if (cur_disp_order_hint >= (1 << (DISPLAY_ORDER_HINT_BITS - 1)))
6757
0
    avm_internal_error(&cm->error, AVM_CODEC_ERROR,
6758
0
                       "Derived display order hint is invalid");
6759
0
  return cur_disp_order_hint;
6760
1
}
6761
6762
static void read_frame_max_bvp_drl_bits(AV2_COMMON *const cm,
6763
16.3k
                                        struct avm_read_bit_buffer *rb) {
6764
16.3k
  FeatureFlags *const features = &cm->features;
6765
16.3k
  const SequenceHeader *const seq_params = &cm->seq_params;
6766
16.3k
  features->max_bvp_drl_bits = seq_params->def_max_bvp_drl_bits;
6767
16.3k
  if (seq_params->allow_frame_max_bvp_drl_bits) {
6768
14.5k
    features->max_bvp_drl_bits =
6769
14.5k
        avm_rb_read_primitive_ref_quniform(
6770
14.5k
            rb, MAX_MAX_IBC_DRL_BITS - MIN_MAX_IBC_DRL_BITS + 1,
6771
14.5k
            seq_params->def_max_bvp_drl_bits - MIN_MAX_IBC_DRL_BITS) +
6772
14.5k
        MIN_MAX_IBC_DRL_BITS;
6773
14.5k
  }
6774
16.3k
}
6775
static INLINE void read_intrabc_params(AV2_COMMON *const cm,
6776
16.3k
                                       struct avm_read_bit_buffer *rb) {
6777
16.3k
  CurrentFrame *const current_frame = &cm->current_frame;
6778
16.3k
  FeatureFlags *const features = &cm->features;
6779
16.3k
  features->allow_intrabc = avm_rb_read_bit(rb);
6780
6781
16.3k
  if (features->allow_intrabc) {
6782
16.3k
    if (current_frame->frame_type == KEY_FRAME ||
6783
16.3k
        current_frame->frame_type == INTRA_ONLY_FRAME) {
6784
16.3k
      features->allow_global_intrabc = avm_rb_read_bit(rb);
6785
16.3k
      features->allow_local_intrabc =
6786
16.3k
          features->allow_global_intrabc ? avm_rb_read_bit(rb) : 1;
6787
16.3k
    } else {
6788
0
      features->allow_global_intrabc = 0;
6789
0
      features->allow_local_intrabc = features->allow_intrabc;
6790
0
    }
6791
16.3k
    read_frame_max_bvp_drl_bits(cm, rb);
6792
16.3k
  }
6793
16.3k
}
6794
static INLINE void read_screen_content_params(AV2_COMMON *const cm,
6795
16.3k
                                              struct avm_read_bit_buffer *rb) {
6796
16.3k
  const SequenceHeader *const seq_params = &cm->seq_params;
6797
16.3k
  FeatureFlags *const features = &cm->features;
6798
6799
16.3k
  if (seq_params->force_screen_content_tools == 2) {
6800
16.2k
    features->allow_screen_content_tools = avm_rb_read_bit(rb);
6801
16.2k
  } else {
6802
97
    features->allow_screen_content_tools =
6803
97
        seq_params->force_screen_content_tools;
6804
97
  }
6805
6806
16.3k
  if (features->allow_screen_content_tools) {
6807
16.2k
    if (seq_params->force_integer_mv == 2) {
6808
16.2k
      features->cur_frame_force_integer_mv = avm_rb_read_bit(rb);
6809
16.2k
    } else {
6810
0
      features->cur_frame_force_integer_mv = seq_params->force_integer_mv;
6811
0
    }
6812
16.2k
  } else {
6813
118
    features->cur_frame_force_integer_mv = 0;
6814
118
  }
6815
16.3k
}
6816
6817
16.3k
static void set_primary_ref_frame_and_ctx(AV2Decoder *pbi) {
6818
16.3k
  AV2_COMMON *const cm = &pbi->common;
6819
16.3k
  const SequenceHeader *const seq_params = &cm->seq_params;
6820
16.3k
  CurrentFrame *const current_frame = &cm->current_frame;
6821
16.3k
  FeatureFlags *const features = &cm->features;
6822
6823
16.3k
  if (!seq_params->single_picture_header_flag) {
6824
1
    int tmp_ref_frame[2] = { 0 };
6825
1
    choose_primary_secondary_ref_frame(cm, tmp_ref_frame,
6826
1
                                       pbi->signal_primary_ref_frame);
6827
1
    features->derived_primary_ref_frame = tmp_ref_frame[0];
6828
1
    features->derived_secondary_ref_frame = tmp_ref_frame[1];
6829
6830
1
    if (!pbi->signal_primary_ref_frame) {
6831
0
      features->primary_ref_frame = features->derived_primary_ref_frame;
6832
0
    }
6833
1
  }
6834
6835
  // For primary_ref_frame and derived_primary_ref_frame, if one of them is
6836
  // PRIMARY_REF_NONE, the other one is also PRIMARY_REF_NONE.
6837
16.3k
  if (features->derived_primary_ref_frame == PRIMARY_REF_NONE ||
6838
16.3k
      features->primary_ref_frame == PRIMARY_REF_NONE) {
6839
16.3k
    features->primary_ref_frame = PRIMARY_REF_NONE;
6840
16.3k
    features->derived_primary_ref_frame = PRIMARY_REF_NONE;
6841
16.3k
    features->cross_frame_context = CROSS_FRAME_CONTEXT_DISABLED;
6842
16.3k
  }
6843
16.3k
  assert(IMPLIES(features->derived_primary_ref_frame == PRIMARY_REF_NONE,
6844
16.3k
                 features->primary_ref_frame == PRIMARY_REF_NONE));
6845
16.3k
  assert(IMPLIES(features->primary_ref_frame == PRIMARY_REF_NONE,
6846
16.3k
                 features->derived_primary_ref_frame == PRIMARY_REF_NONE));
6847
6848
16.3k
  if (features->primary_ref_frame >= cm->ref_frames_info.num_total_refs &&
6849
16.3k
      features->primary_ref_frame != PRIMARY_REF_NONE) {
6850
0
    avm_internal_error(&cm->error, AVM_CODEC_ERROR,
6851
0
                       "Invalid primary_ref_frame");
6852
0
  }
6853
16.3k
  if (get_ref_frame_buf(cm, features->primary_ref_frame) != NULL &&
6854
0
      get_ref_frame_buf(cm, features->primary_ref_frame)->is_restricted) {
6855
0
    avm_internal_error(&cm->error, AVM_CODEC_ERROR,
6856
0
                       "primary_ref_frame points a restricted reference");
6857
0
  }
6858
16.3k
  if (cm->features.primary_ref_frame == PRIMARY_REF_NONE ||
6859
16.3k
      cm->features.cross_frame_context == CROSS_FRAME_CONTEXT_DISABLED) {
6860
    // use the default frame context values
6861
16.3k
    av2_setup_past_independence(cm);
6862
16.3k
  } else {
6863
0
    *cm->fc = get_primary_ref_frame_buf(cm, cm->features.primary_ref_frame)
6864
0
                  ->frame_context;
6865
0
  }
6866
6867
16.3k
  if (!cm->fc->initialized) {
6868
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
6869
0
                       "Uninitialized entropy context.");
6870
0
  }
6871
6872
16.3k
  if (current_frame->frame_type != KEY_FRAME) {
6873
0
    cm->prev_frame =
6874
0
        get_primary_ref_frame_buf(cm, features->derived_primary_ref_frame);
6875
0
    if (features->derived_primary_ref_frame != PRIMARY_REF_NONE &&
6876
0
        get_primary_ref_frame_buf(cm, features->derived_primary_ref_frame) ==
6877
0
            NULL) {
6878
0
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
6879
0
                         "Reference frame containing this frame's initial "
6880
0
                         "frame context is unavailable.");
6881
0
    }
6882
0
  }
6883
16.3k
}
6884
6885
static void read_frame_max_drl_bits(AV2_COMMON *const cm,
6886
0
                                    struct avm_read_bit_buffer *rb) {
6887
0
  FeatureFlags *const features = &cm->features;
6888
0
  const SequenceHeader *const seq_params = &cm->seq_params;
6889
0
  features->max_drl_bits = seq_params->def_max_drl_bits;
6890
0
  if (seq_params->allow_frame_max_drl_bits) {
6891
0
    features->max_drl_bits =
6892
0
        avm_rb_read_primitive_ref_quniform(
6893
0
            rb, MAX_MAX_DRL_BITS - MIN_MAX_DRL_BITS + 1,
6894
0
            seq_params->def_max_drl_bits - MIN_MAX_DRL_BITS) +
6895
0
        MIN_MAX_DRL_BITS;
6896
0
  }
6897
0
}
6898
6899
0
static void reset_buffer_other_than_OLK(AV2Decoder *pbi) {
6900
0
  AV2_COMMON *const cm = &pbi->common;
6901
0
  const SequenceHeader *const seq_params = &cm->seq_params;
6902
0
  BufferPool *const pool = cm->buffer_pool;
6903
0
  int ref_flags_to_keep = 0;
6904
0
  for (int layer = 0; layer <= seq_params->max_mlayer_id; layer++) {
6905
0
    if (cm->olk_refresh_frame_flags[layer] != -1)
6906
0
      ref_flags_to_keep |= cm->olk_refresh_frame_flags[layer];
6907
0
    if (cm->olk_co_vcl_refresh_frame_flags[layer] != -1)
6908
0
      ref_flags_to_keep |= cm->olk_co_vcl_refresh_frame_flags[layer];
6909
0
  }
6910
0
  for (int ref_index = 0; ref_index < seq_params->ref_frames; ref_index++) {
6911
0
    if (!((ref_flags_to_keep >> ref_index) & 1u) &&
6912
0
        cm->ref_frame_map[ref_index] != NULL &&
6913
0
        cm->ref_frame_map[ref_index]->long_term_id == -1) {
6914
0
      decrease_ref_count(cm->ref_frame_map[ref_index], pool);
6915
0
      cm->ref_frame_map[ref_index] = NULL;
6916
0
      if (pbi->random_accessed) pbi->valid_for_referencing[ref_index] = 1;
6917
0
    }
6918
0
  }
6919
6920
0
  for (int layer = 0; layer <= seq_params->max_mlayer_id; layer++) {
6921
0
    cm->olk_refresh_frame_flags[layer] = -1;
6922
0
    cm->olk_co_vcl_refresh_frame_flags[layer] = -1;
6923
0
    cm->prev_olk_co_vcl_refresh_frame_flags[layer] = -1;
6924
0
  }
6925
0
}
6926
6927
0
int av2_is_regular_non_olk_obu(OBU_TYPE obu_type) {
6928
0
  return obu_type == OBU_REGULAR_SEF || obu_type == OBU_REGULAR_TIP ||
6929
0
         obu_type == OBU_SWITCH || obu_type == OBU_RAS_FRAME ||
6930
0
         obu_type == OBU_BRIDGE_FRAME || obu_type == OBU_REGULAR_TILE_GROUP;
6931
0
}
6932
6933
93.1k
int av2_is_regular_vcl_obu(OBU_TYPE obu_type) {
6934
93.1k
  return (obu_type == OBU_REGULAR_SEF || obu_type == OBU_REGULAR_TIP ||
6935
93.1k
          obu_type == OBU_REGULAR_TILE_GROUP || obu_type == OBU_BRIDGE_FRAME ||
6936
92.8k
          obu_type == OBU_SWITCH || obu_type == OBU_RAS_FRAME ||
6937
92.8k
          obu_type == OBU_OPEN_LOOP_KEY);
6938
93.1k
}
6939
// Check if the current frame's layer is within the selected operating point
6940
// using the DecOperatingPointParams structure.
6941
static int is_layer_within_op_profiles(AV2Decoder *pbi,
6942
                                       const int current_tlayer_id,
6943
0
                                       const int current_mlayer_id) {
6944
0
  const DecOperatingPointParams *params = &pbi->dec_op_params;
6945
0
  if (!params->isValid || !params->dec_op) return 0;
6946
0
  const int xlayer_id = pbi->common.xlayer_id;
6947
0
  const OpsMLayerInfo *info = &params->dec_op->mlayer_info;
6948
  // Check if mlayer is in the OP
6949
0
  if (!((info->ops_mlayer_map[xlayer_id] >> current_mlayer_id) & 1)) return 0;
6950
  // Check if tlayer is in the OP for this mlayer
6951
0
  if (!((info->ops_tlayer_map[xlayer_id][current_mlayer_id] >>
6952
0
         current_tlayer_id) &
6953
0
        1))
6954
0
    return 0;
6955
0
  return 1;
6956
0
}
6957
6958
// Derive operating point masks for mlayer and tlayer from the selected
6959
// operating point in DecOperatingPointParams.
6960
static void create_op_masks_from_profiles(AV2Decoder *pbi, int *tlayer_op_mask,
6961
0
                                          int *mlayer_op_mask) {
6962
0
  const DecOperatingPointParams *params = &pbi->dec_op_params;
6963
0
  const int xlayer_id = pbi->common.xlayer_id;
6964
0
  *mlayer_op_mask = params->dec_op->mlayer_info.ops_mlayer_map[xlayer_id];
6965
  // Compute combined tlayer mask: union of all per-mlayer tlayer maps
6966
0
  *tlayer_op_mask = 0;
6967
0
  for (int j = 0; j < MAX_NUM_MLAYERS; j++) {
6968
0
    if (*mlayer_op_mask & (1 << j)) {
6969
0
      *tlayer_op_mask |=
6970
0
          params->dec_op->mlayer_info.ops_tlayer_map[xlayer_id][j];
6971
0
    }
6972
0
  }
6973
0
}
6974
6975
// Returns 1 if the given layer subset has a missing dependency, i.e. a
6976
// retained layer depends on a dropped layer according to the dependency maps.
6977
static int check_missing_layer_dependency(const AV2_COMMON *cm, int mlayer_mask,
6978
0
                                          int tlayer_mask) {
6979
0
  for (int cur_mlayer_id = 0; cur_mlayer_id <= cm->mlayer_id; cur_mlayer_id++) {
6980
0
    if (!is_layer_dropped(cur_mlayer_id, mlayer_mask)) {
6981
0
      for (int ref_mlayer_id = 0; ref_mlayer_id < cur_mlayer_id;
6982
0
           ref_mlayer_id++) {
6983
0
        if (cm->seq_params
6984
0
                .mlayer_dependency_map[cur_mlayer_id][ref_mlayer_id] &&
6985
0
            is_layer_dropped(ref_mlayer_id, mlayer_mask)) {
6986
0
          return 1;
6987
0
        }
6988
0
      }
6989
0
      for (int cur_tlayer_id = 0; cur_tlayer_id <= cm->tlayer_id;
6990
0
           cur_tlayer_id++) {
6991
0
        if (!is_layer_dropped(cur_tlayer_id, tlayer_mask)) {
6992
0
          for (int ref_tlayer_id = 0; ref_tlayer_id < cur_tlayer_id;
6993
0
               ref_tlayer_id++) {
6994
0
            if (cm->seq_params
6995
0
                    .tlayer_dependency_map[cur_mlayer_id][cur_tlayer_id]
6996
0
                                          [ref_tlayer_id] &&
6997
0
                is_layer_dropped(ref_tlayer_id, tlayer_mask)) {
6998
0
              return 1;
6999
0
            }
7000
0
          }
7001
0
        }
7002
0
      }
7003
0
    }
7004
0
  }
7005
0
  return 0;
7006
0
}
7007
7008
static void check_consistent_disp_order_hint_derivation(AV2Decoder *pbi,
7009
                                                        OBU_TYPE obu_type,
7010
17
                                                        bool random_accessed) {
7011
17
  AV2_COMMON *const cm = &pbi->common;
7012
7013
  // Note: The following if block implements bitstream constraint checks for
7014
  // consistent display order hint derivation when (embedded or temporal)
7015
  // layers are selectively dropped based on operating points. The following
7016
  // code provides checks for all the possible operating point combinations
7017
  // and decoders may choose to simplify this check depending on the desired
7018
  // operating point(s) specified in the operating point set (OPS).
7019
17
  if (pbi->dec_op_params.isValid &&
7020
0
      is_layer_within_op_profiles(pbi, cm->tlayer_id, cm->mlayer_id)) {
7021
0
    CurrentFrame *const current_frame = &cm->current_frame;
7022
0
    const int disp_order_unconstrained = current_frame->display_order_hint;
7023
0
    int disp_order_op_constrained = 0;
7024
    // number of layer-drop masks
7025
0
    const int num_mlayer_masks = 1 << (cm->mlayer_id + 1);
7026
0
    const int num_tlayer_masks = 1 << (cm->tlayer_id + 1);
7027
    // derive operating point masks for mlayer and tlayer
7028
0
    int op_mlayer_mask, op_tlayer_mask;
7029
0
    create_op_masks_from_profiles(pbi, &op_tlayer_mask, &op_mlayer_mask);
7030
    // Check consistency for subsets of OPs that would include the current
7031
    // frame. Skip subsets where the current frame's layer would be dropped,
7032
    // as those do not correspond to valid operating points for this frame.
7033
0
    for (int ml = 0; ml < num_mlayer_masks; ml++) {
7034
0
      for (int tl = 0; tl < num_tlayer_masks; tl++) {
7035
0
        int mlayer_mask = ml & op_mlayer_mask;
7036
0
        int tlayer_mask = tl & op_tlayer_mask;
7037
        // Skip subsets that would drop the current frame's layer.
7038
0
        if (is_layer_dropped(cm->mlayer_id, mlayer_mask) ||
7039
0
            is_layer_dropped(cm->tlayer_id, tlayer_mask))
7040
0
          continue;
7041
        // Skip subsets with unsatisfied layer dependencies.
7042
0
        if (check_missing_layer_dependency(cm, mlayer_mask, tlayer_mask))
7043
0
          continue;
7044
0
        disp_order_op_constrained = get_disp_order_hint(
7045
0
            cm, obu_type, random_accessed, /*is_op_constrained=*/true,
7046
0
            mlayer_mask, tlayer_mask);
7047
0
        if (disp_order_unconstrained != disp_order_op_constrained) {
7048
0
          avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7049
0
                             "Inconsistent display order hint derivation "
7050
0
                             "accross different operating points.");
7051
0
        }
7052
0
      }
7053
0
    }
7054
0
  }
7055
17
}
7056
7057
static int read_show_existing_frame(AV2Decoder *pbi, bool is_regular_obu,
7058
0
                                    struct avm_read_bit_buffer *rb) {
7059
0
  AV2_COMMON *const cm = &pbi->common;
7060
0
  const SequenceHeader *const seq_params = &cm->seq_params;
7061
0
  CurrentFrame *const current_frame = &cm->current_frame;
7062
0
  BufferPool *const pool = cm->buffer_pool;
7063
0
  cm->show_existing_frame = 1;
7064
0
  init_bru_params(cm);
7065
7066
0
  if (is_regular_obu && pbi->olk_encountered &&
7067
0
      pbi->this_is_first_vcl_obu_in_tu) {
7068
0
    lock_buffer_pool(pool);
7069
0
    reset_buffer_other_than_OLK(pbi);
7070
0
    unlock_buffer_pool(pool);
7071
0
  }
7072
7073
  // Show an existing frame directly.
7074
0
  const int existing_frame_idx =
7075
0
      avm_rb_read_literal(rb, seq_params->ref_frames_log2);
7076
7077
0
  if (existing_frame_idx >= seq_params->ref_frames) {
7078
0
    avm_internal_error(
7079
0
        &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7080
0
        "Existing frame idx must be less than %d but is set to %d",
7081
0
        seq_params->ref_frames, existing_frame_idx);
7082
0
  }
7083
0
  RefCntBuffer *const frame_to_show = cm->ref_frame_map[existing_frame_idx];
7084
0
  if (frame_to_show == NULL) {
7085
0
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7086
0
                       "Buffer does not contain a decoded frame");
7087
0
  }
7088
0
  if (frame_to_show->is_restricted) {
7089
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
7090
0
                       "Invalid SEF Ref: restricted reference buffer");
7091
0
  }
7092
0
  cm->sef_ref_fb_idx = existing_frame_idx;
7093
0
  cm->derive_sef_order_hint = avm_rb_read_bit(rb);
7094
0
  cm->cur_frame->mlayer_id = cm->mlayer_id;
7095
0
  cm->cur_frame->xlayer_id = cm->xlayer_id;
7096
0
  cm->cur_frame->stream_id = av2_get_stream_index(cm, cm->xlayer_id);
7097
7098
0
  if (!cm->derive_sef_order_hint) {
7099
0
    current_frame->order_hint = avm_rb_read_literal(
7100
0
        rb, seq_params->order_hint_info.order_hint_bits_minus_1 + 1);
7101
7102
0
    current_frame->display_order_hint = get_disp_order_hint(
7103
0
        cm, is_regular_obu ? OBU_REGULAR_SEF : OBU_LEADING_SEF, false, false,
7104
0
        -1, -1);
7105
0
    check_consistent_disp_order_hint_derivation(
7106
0
        pbi, is_regular_obu ? OBU_REGULAR_SEF : OBU_LEADING_SEF,
7107
0
        /*random_accessed=*/false);
7108
0
    current_frame->frame_number = current_frame->order_hint;
7109
    // Since a SEF frame is not used as a reference frame, its display order
7110
    // hint cannot be used to derive display order hints of subsequent frames.
7111
    // To guarantee that, the display order hint of the SEF frame should not be
7112
    // bigger than the max_disp_order_hint
7113
0
    unsigned int max_disp_order_hint = 0;
7114
0
    for (int map_idx = 0; map_idx < cm->seq_params.ref_frames; map_idx++) {
7115
      // Get reference frame buffer
7116
0
      const RefCntBuffer *const buf = cm->ref_frame_map[map_idx];
7117
0
      if (buf == NULL ||
7118
0
          !is_tlayer_scalable_and_dependent(&cm->seq_params, cm->tlayer_id,
7119
0
                                            buf->tlayer_id, cm->mlayer_id) ||
7120
0
          !is_mlayer_scalable_and_dependent(&cm->seq_params, cm->mlayer_id,
7121
0
                                            buf->mlayer_id))
7122
0
        continue;
7123
0
      if (buf->display_order_hint > max_disp_order_hint)
7124
0
        max_disp_order_hint = buf->display_order_hint;
7125
0
    }
7126
0
    cm->cur_frame->order_hint = current_frame->order_hint;
7127
0
    cm->cur_frame->display_order_hint = current_frame->display_order_hint;
7128
0
    resize_context_buffers(cm, frame_to_show->width, frame_to_show->height);
7129
0
    setup_buffer_pool(cm);
7130
0
    avm_yv12_copy_frame(&frame_to_show->buf, &cm->cur_frame->buf,
7131
0
                        av2_num_planes(cm));
7132
0
  } else {
7133
0
    if (frame_to_show->implicit_output_picture ||
7134
0
        frame_to_show->immediate_output_picture) {
7135
0
      avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7136
0
                         "the reference frame should be a hidden frame when "
7137
0
                         "derive_sef_order_hint is true");
7138
0
      return 0;
7139
0
    }
7140
0
    current_frame->order_hint = cm->cur_frame->order_hint =
7141
0
        frame_to_show->order_hint;
7142
0
    current_frame->display_order_hint = cm->cur_frame->display_order_hint =
7143
0
        frame_to_show->display_order_hint;
7144
0
  }
7145
7146
0
  if (is_regular_obu && pbi->olk_encountered) {
7147
0
    if (pbi->last_olk_tu_display_order_hint == -1 &&
7148
0
        !pbi->this_is_first_vcl_obu_in_tu) {
7149
      // First non-hidden regular frame after a hidden OLK is this SEF (SEFs
7150
      // are always shown).
7151
0
      pbi->last_olk_tu_display_order_hint = current_frame->display_order_hint;
7152
0
    }
7153
0
    if (pbi->this_is_first_vcl_obu_in_tu) pbi->olk_encountered = 0;
7154
0
  }
7155
7156
0
  lock_buffer_pool(pool);
7157
0
  assert(frame_to_show->ref_count > 0);
7158
  // cm->cur_frame should be the buffer referenced by the return value
7159
  // of the get_free_fb() call in assign_cur_frame_new_fb() (called by
7160
  // av2_receive_compressed_data()), so the ref_count should be 1.
7161
0
  assert(cm->cur_frame->ref_count == 1);
7162
  // assign_frame_buffer_p() decrements ref_count directly rather than
7163
  // call decrease_ref_count(). If cm->cur_frame->raw_frame_buffer has
7164
  // already been allocated, it will not be released by
7165
  // assign_frame_buffer_p()!
7166
0
  assert(IMPLIES(cm->derive_sef_order_hint,
7167
0
                 !cm->cur_frame->raw_frame_buffer.data));
7168
7169
0
  FrameHash raw_frame_hash = cm->cur_frame->raw_frame_hash;
7170
0
  FrameHash grain_frame_hash = cm->cur_frame->grain_frame_hash;
7171
0
  if (cm->derive_sef_order_hint)
7172
0
    assign_frame_buffer_p(&cm->cur_frame, frame_to_show);
7173
7174
  // Combine any Decoded Frame Header metadata that was parsed before
7175
  // the referenced frame with any parsed before this
7176
  // show_existing_frame header, e.g. raw frame hash values before the
7177
  // referenced coded frame and post film grain hash values before this
7178
  // header.
7179
0
  if (raw_frame_hash.is_present) cm->cur_frame->raw_frame_hash = raw_frame_hash;
7180
0
  if (grain_frame_hash.is_present)
7181
0
    cm->cur_frame->grain_frame_hash = grain_frame_hash;
7182
0
  unlock_buffer_pool(pool);
7183
7184
0
  cm->lf.apply_deblocking_filter[0] = 0;
7185
0
  cm->lf.apply_deblocking_filter[1] = 0;
7186
0
  cm->immediate_output_picture = 1;
7187
  // It is a requirement of bitstream conformance that when
7188
  // show_existing_frame is used to show a previous frame with derived display
7189
  // order hint, the frame is output via the show_existing_frame mechanism at
7190
  // most once.
7191
0
  if (cm->derive_sef_order_hint && frame_to_show->frame_output_done) {
7192
0
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7193
0
                       "Buffer does not contain a showable frame");
7194
0
  }
7195
0
  setup_film_grain(pbi, rb);
7196
0
  current_frame->refresh_frame_flags = 0;
7197
0
  return 0;
7198
0
}
7199
7200
static void read_frame_opfl_refine_type(AV2_COMMON *const cm,
7201
0
                                        struct avm_read_bit_buffer *rb) {
7202
0
  if (cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
7203
0
    cm->features.opfl_refine_type =
7204
0
        (cm->seq_params.enable_opfl_refine == AVM_OPFL_REFINE_NONE ||
7205
0
         !cm->seq_params.enable_tip_refinemv)
7206
0
            ? REFINE_NONE
7207
0
            : REFINE_ALL;
7208
0
    return;
7209
0
  }
7210
7211
0
  if (cm->seq_params.enable_opfl_refine == AVM_OPFL_REFINE_AUTO) {
7212
0
    if (avm_rb_read_bit(rb)) {
7213
0
      cm->features.opfl_refine_type = REFINE_SWITCHABLE;
7214
0
    } else {
7215
0
      cm->features.opfl_refine_type =
7216
0
          avm_rb_read_bit(rb) ? REFINE_ALL : REFINE_NONE;
7217
0
    }
7218
0
  } else {
7219
0
    cm->features.opfl_refine_type = cm->seq_params.enable_opfl_refine;
7220
0
  }
7221
0
}
7222
7223
0
int ras_frame_refresh_frame_flags_derivation(AV2Decoder *pbi) {
7224
0
  AV2_COMMON *const cm = &pbi->common;
7225
0
  int refresh_frame_flags = (1 << cm->seq_params.ref_frames) - 1;
7226
0
  for (int i = 0; i < cm->seq_params.ref_frames; i++) {
7227
0
    if (cm->ref_frame_map[i] == NULL) continue;
7228
0
    for (int j = 0; j < cm->num_ref_key_frames; j++) {
7229
0
      if (cm->ref_long_term_ids[j] == cm->ref_frame_map[i]->long_term_id) {
7230
0
        refresh_frame_flags &= ~(1 << i);
7231
0
      }
7232
0
    }
7233
0
  }
7234
0
  return refresh_frame_flags;
7235
0
}
7236
7237
// This function marks reference frames as valid for referencing if they are
7238
// present in the current RAS frame's long term ids.
7239
// Note that we handle the case where there are multiple RAS frames (at
7240
// different embedded layers) in a temporal unit, by clearing the
7241
// valid_for_referencing flags and current and dependent mlayer reference frames
7242
// only.
7243
0
void mark_reference_frames_with_long_term_ids(AV2Decoder *pbi) {
7244
0
  AV2_COMMON *const cm = &pbi->common;
7245
0
  for (int i = 0; i < cm->seq_params.ref_frames; i++) {
7246
0
    if (cm->ref_frame_map[i] != NULL &&
7247
0
        !is_mlayer_transitively_dependent(
7248
0
            &cm->seq_params, cm->ref_frame_map[i]->mlayer_id, cm->mlayer_id)) {
7249
0
      continue;
7250
0
    }
7251
0
    pbi->valid_for_referencing[i] = 0;
7252
0
    for (int j = 0; j < cm->num_ref_key_frames; j++) {
7253
0
      if (cm->ref_frame_map[i] != NULL &&
7254
0
          cm->ref_long_term_ids[j] == cm->ref_frame_map[i]->long_term_id)
7255
0
        pbi->valid_for_referencing[i] = 1;
7256
0
    }
7257
0
  }
7258
0
}
7259
7260
0
void check_long_term_ids_exist(AV2Decoder *pbi) {
7261
0
  AV2_COMMON *const cm = &pbi->common;
7262
0
  for (int j = 0; j < cm->num_ref_key_frames; j++) {
7263
0
    int found = 0;
7264
0
    for (int i = 0; i < cm->seq_params.ref_frames; i++) {
7265
0
      if (cm->ref_frame_map[i] != NULL &&
7266
0
          cm->ref_long_term_ids[j] == cm->ref_frame_map[i]->long_term_id) {
7267
0
        found = 1;
7268
0
        break;
7269
0
      }
7270
0
    }
7271
0
    if (found == 0) {
7272
0
      avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7273
0
                         "Required long term reference not available");
7274
0
    }
7275
0
  }
7276
0
}
7277
7278
0
static void activate_atlas_segment(AV2Decoder *pbi) {
7279
0
  AV2_COMMON *const cm = &pbi->common;
7280
0
  bool atlas_found = false;
7281
0
  int xlayer_id;
7282
0
  int atlas_lcr_id;
7283
0
  xlayer_id = cm->lcr_params.xlayer_id;
7284
0
  if (cm->lcr_params.is_global) {
7285
0
    atlas_lcr_id = cm->lcr_params.global_lcr.lcr_global_atlas_id;
7286
0
  } else {
7287
0
    atlas_lcr_id = cm->lcr_params.local_lcr.lcr_local_atlas_id;
7288
0
  }
7289
0
  for (int i = 0; i < pbi->atlas_counter[xlayer_id]; i++) {
7290
0
    if (pbi->atlas_list[xlayer_id][i].atlas_segment_id == atlas_lcr_id) {
7291
0
      pbi->active_atlas_segment_info = &pbi->atlas_list[xlayer_id][i];
7292
0
      atlas_found = true;
7293
0
      break;
7294
0
    }
7295
0
  }
7296
0
  if (atlas_found) {
7297
0
    cm->atlas_params = *pbi->active_atlas_segment_info;
7298
0
  } else {
7299
0
    memset(&cm->atlas_params, 0, sizeof(struct AtlasSegmentInfo));
7300
0
  }
7301
0
}
7302
7303
// Find the active LCR for the given xlayer_id and seq_lcr_id.
7304
// First searches for a local LCR whose lcr_local_id matches seq_lcr_id,
7305
// then falls back to the global LCR.
7306
static LayerConfigurationRecord *find_active_lcr(AV2Decoder *pbi, int xlayer_id,
7307
49
                                                 int seq_lcr_id) {
7308
49
  LayerConfigurationRecord *lcr = NULL;
7309
  // Option 1: search for a local LCR for the current layer whose
7310
  // lcr_global_id matches seq_lcr_id. seq_lcr_id is a global LCR ID, and
7311
  // local LCRs are linked to a global LCR via local_lcr->lcr_global_id.
7312
49
  if (xlayer_id < GLOBAL_XLAYER_ID) {
7313
441
    for (int i = 0; i < MAX_NUM_LCR; i++) {
7314
392
      LayerConfigurationRecord *candidate = &pbi->lcr_list[xlayer_id][i];
7315
392
      if (candidate->valid && !candidate->is_global &&
7316
0
          candidate->local_lcr.lcr_local_id == seq_lcr_id) {
7317
0
        lcr = candidate;
7318
0
        break;
7319
0
      }
7320
392
    }
7321
49
  }
7322
  // Option 2: no local LCR found for this layer; use the global LCR whose
7323
  // lcr_global_config_record_id matches seq_lcr_id directly.
7324
49
  if (lcr == NULL) {
7325
49
    LayerConfigurationRecord *global_lcr =
7326
49
        &pbi->lcr_list[GLOBAL_XLAYER_ID][seq_lcr_id];
7327
49
    if (global_lcr->valid && global_lcr->is_global) {
7328
0
      lcr = global_lcr;
7329
0
    }
7330
49
  }
7331
49
  return lcr;
7332
49
}
7333
7334
static void activate_layer_configuration_record(AV2Decoder *pbi,
7335
45
                                                int seq_lcr_id) {
7336
45
  AV2_COMMON *const cm = &pbi->common;
7337
45
  LayerConfigurationRecord *lcr =
7338
45
      find_active_lcr(pbi, cm->xlayer_id, seq_lcr_id);
7339
45
  if (lcr != NULL) {
7340
0
    if (lcr->lcr_from_leading) {
7341
0
      avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7342
0
                         "LCR was signalled in a leading temporal "
7343
0
                         "unit and not re-signalled");
7344
0
    }
7345
0
    pbi->active_lcr = lcr;
7346
0
    cm->lcr_params = *pbi->active_lcr;
7347
7348
    // Conformance: when monotonic_output_order_flag is 0 in any activated
7349
    // sequence header, lcr_doh_constraint_flag shall be 1.
7350
0
    if (lcr->is_global && !cm->seq_params.monotonic_output_order_flag &&
7351
0
        !lcr->global_lcr.lcr_doh_constraint_flag) {
7352
0
      avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7353
0
                         "lcr_doh_constraint_flag must be 1 when "
7354
0
                         "monotonic_output_order_flag is 0");
7355
0
    }
7356
7357
    // If the activated LCR is a local LCR, also store the parent global LCR
7358
    // so that embedded layer info can fall back to it.
7359
0
    if (!lcr->is_global) {
7360
0
      int global_id = lcr->local_lcr.lcr_global_id;
7361
0
      if (global_id != LCR_ID_UNSPECIFIED) {
7362
0
        LayerConfigurationRecord *parent_glcr =
7363
0
            &pbi->lcr_list[GLOBAL_XLAYER_ID][global_id];
7364
0
        if (parent_glcr->valid && parent_glcr->is_global) {
7365
0
          cm->global_lcr_params = *parent_glcr;
7366
          // Conformance: when a local LCR is present and its parent global LCR
7367
          // has xlayer_info for the same extended layer, the local LCR's
7368
          // xlayer_info shall be the same as the global LCR's xlayer_info.
7369
0
          const GlobalLayerConfigurationRecord *glcr = &parent_glcr->global_lcr;
7370
0
          for (int i = 0; i < glcr->LcrMaxNumXLayerCount; i++) {
7371
0
            if (glcr->LcrXLayerID[i] == lcr->xlayer_id) {
7372
0
              if (memcmp(&lcr->local_lcr.xlayer_info, &glcr->xlayer_info[i],
7373
0
                         sizeof(lcr->local_lcr.xlayer_info)) != 0) {
7374
0
                avm_internal_error(
7375
0
                    &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7376
0
                    "Local LCR xlayer_info for xlayer_id %d does not match "
7377
0
                    "the parent global LCR xlayer_info",
7378
0
                    lcr->xlayer_id);
7379
0
              }
7380
0
              break;
7381
0
            }
7382
0
          }
7383
0
        } else {
7384
0
          memset(&cm->global_lcr_params, 0, sizeof(cm->global_lcr_params));
7385
0
        }
7386
0
      } else {
7387
        // No Global LCR associated with this Local LCR.
7388
0
        memset(&cm->global_lcr_params, 0, sizeof(cm->global_lcr_params));
7389
0
      }
7390
0
    } else {
7391
0
      memset(&cm->global_lcr_params, 0, sizeof(cm->global_lcr_params));
7392
0
    }
7393
0
    activate_atlas_segment(pbi);
7394
45
  } else {
7395
45
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7396
45
                       "Unsupported LCR id in the Sequence Header.\n");
7397
45
  }
7398
45
}
7399
7400
// This function provides conformance checks for the LCR, where the mlayer and
7401
// tlayer presence information in lcr_mlayer_map and lcr_tlayer_map do not
7402
// contradict with the dependency map information from the sequence header.
7403
static void check_lcr_mlayer_tlayer_conformance(
7404
    const struct SequenceHeader *const seq_header,
7405
    const struct EmbeddedLayerInfo *mlayer_params,
7406
0
    struct avm_internal_error_info *info) {
7407
0
  const int mlayer_map = mlayer_params->lcr_mlayer_map;
7408
0
  for (int cur_mlayer_id = 0; cur_mlayer_id < MAX_NUM_MLAYERS;
7409
0
       cur_mlayer_id++) {
7410
0
    for (int ref_mlayer_id = 0; ref_mlayer_id < cur_mlayer_id;
7411
0
         ref_mlayer_id++) {
7412
0
      if (seq_header->mlayer_dependency_map[cur_mlayer_id][ref_mlayer_id] ==
7413
0
          1) {
7414
0
        if ((mlayer_map & (1 << cur_mlayer_id)) &&
7415
0
            (mlayer_map & (1 << ref_mlayer_id)) == 0) {
7416
0
          avm_internal_error(
7417
0
              info, AVM_CODEC_UNSUP_BITSTREAM,
7418
0
              "Inconsistent mlayer dependency: In the activated sequence "
7419
0
              "header, mlayer_dependency_map[%d][%d] is equal to 1, indicating "
7420
0
              "an mlayer with ID=%d depends on an mlayer with ID=%d, while "
7421
0
              "lcr_mlayer_map indicates that an mlayer with ID=%d is "
7422
0
              "not present.",
7423
0
              cur_mlayer_id, ref_mlayer_id, cur_mlayer_id, ref_mlayer_id,
7424
0
              ref_mlayer_id);
7425
0
        }
7426
0
      }
7427
0
    }
7428
0
    const int tlayer_map = mlayer_params->lcr_tlayer_map[cur_mlayer_id];
7429
0
    for (int cur_tlayer_id = 0; cur_tlayer_id < MAX_NUM_TLAYERS;
7430
0
         cur_tlayer_id++) {
7431
0
      for (int ref_tlayer_id = 0; ref_tlayer_id < cur_tlayer_id;
7432
0
           ref_tlayer_id++) {
7433
0
        if (seq_header->tlayer_dependency_map[cur_mlayer_id][cur_tlayer_id]
7434
0
                                             [ref_tlayer_id] == 1) {
7435
0
          if ((tlayer_map & (1 << cur_tlayer_id)) &&
7436
0
              (tlayer_map & (1 << ref_tlayer_id)) == 0) {
7437
0
            avm_internal_error(
7438
0
                info, AVM_CODEC_UNSUP_BITSTREAM,
7439
0
                "Inconsistent tlayer dependency: In the activated sequence "
7440
0
                "header, tlayer_dependency_map[%d][%d][%d] is equal to 1, "
7441
0
                "indicating a tlayer with ID=%d depends on a tlayer with "
7442
0
                "ID=%d, while lcr_tlayer_map[%d] indicates that a "
7443
0
                "tlayer with ID=%d is not present.",
7444
0
                cur_mlayer_id, cur_tlayer_id, ref_tlayer_id, cur_tlayer_id,
7445
0
                ref_tlayer_id, cur_mlayer_id, ref_tlayer_id);
7446
0
          }
7447
0
        }
7448
0
      }
7449
0
    }
7450
0
  }
7451
0
}
7452
7453
// This function calls check_lcr_mlayer_tlayer_conformance function to perform
7454
// conformance checks accross the LCRs and xlayers present in the bitstream.
7455
static void check_lcr_layer_map_conformance(struct AV2Decoder *pbi,
7456
2.97k
                                            const int xlayer_id) {
7457
2.97k
  AV2_COMMON *const cm = &pbi->common;
7458
2.97k
  SequenceHeader *const seq_header = &cm->seq_params;
7459
2.97k
  const int seq_lcr_id = seq_header->seq_lcr_id;
7460
7461
2.97k
  if (seq_lcr_id == LCR_ID_UNSPECIFIED) return;
7462
7463
4
  LayerConfigurationRecord *lcr_params =
7464
4
      find_active_lcr(pbi, xlayer_id, seq_lcr_id);
7465
7466
4
  if (lcr_params == NULL) return;
7467
7468
0
  const LCRXLayerInfo *lcr_xlayer_info;
7469
0
  if (lcr_params->is_global) {
7470
0
    const GlobalLayerConfigurationRecord *glb_lcr = &lcr_params->global_lcr;
7471
0
    if (glb_lcr == NULL) return;
7472
0
    for (int i = 0; i < glb_lcr->LcrMaxNumXLayerCount; i++) {
7473
0
      int xLId = glb_lcr->LcrXLayerID[i];
7474
0
      lcr_xlayer_info = &glb_lcr->xlayer_info[xLId];
7475
0
      check_lcr_mlayer_tlayer_conformance(
7476
0
          seq_header, &lcr_xlayer_info->mlayer_params, &cm->error);
7477
0
    }
7478
0
  } else {
7479
0
    const LocalLayerConfigurationRecord *loc_lcr = &lcr_params->local_lcr;
7480
0
    if (loc_lcr == NULL) return;
7481
0
    lcr_xlayer_info = &loc_lcr->xlayer_info;
7482
0
    check_lcr_mlayer_tlayer_conformance(
7483
0
        seq_header, &lcr_xlayer_info->mlayer_params, &cm->error);
7484
0
  }
7485
0
}
7486
7487
// This function provides conformance checks for the OPS, where the mlayer and
7488
// tlayer presence information in ops_mlayer_map and ops_tlayer_map do not
7489
// contradict with the dependency map information from the sequence header.
7490
static void check_ops_mlayer_tlayer_conformance(
7491
    const struct SequenceHeader *const seq_header,
7492
    const struct OpsMLayerInfo *const ops_mlayer_info, int xLId,
7493
161
    struct avm_internal_error_info *info) {
7494
161
  const int mlayer_map = ops_mlayer_info->ops_mlayer_map[xLId];
7495
1.44k
  for (int cur_mlayer_id = 0; cur_mlayer_id < MAX_NUM_MLAYERS;
7496
1.28k
       cur_mlayer_id++) {
7497
5.79k
    for (int ref_mlayer_id = 0; ref_mlayer_id < cur_mlayer_id;
7498
4.50k
         ref_mlayer_id++) {
7499
4.50k
      if (seq_header->mlayer_dependency_map[cur_mlayer_id][ref_mlayer_id] ==
7500
4.50k
          1) {
7501
0
        if ((mlayer_map & (1 << cur_mlayer_id)) &&
7502
0
            (mlayer_map & (1 << ref_mlayer_id)) == 0) {
7503
0
          avm_internal_error(
7504
0
              info, AVM_CODEC_UNSUP_BITSTREAM,
7505
0
              "Inconsistent mlayer dependency: In the activated sequence "
7506
0
              "header, mlayer_dependency_map[%d][%d] is equal to 1, indicating "
7507
0
              "an mlayer with ID=%d depends on an mlayer with ID=%d, while "
7508
0
              "ops_mlayer_map[%d] indicates that an mlayer with ID=%d is not "
7509
0
              "present.",
7510
0
              cur_mlayer_id, ref_mlayer_id, cur_mlayer_id, ref_mlayer_id, xLId,
7511
0
              ref_mlayer_id);
7512
0
        }
7513
0
      }
7514
4.50k
    }
7515
    // Only check ops_tlayer_map for embedded layers present in ops_mlayer_map,
7516
    // as ops_tlayer_map is only read from the bitstream for those layers.
7517
1.28k
    if (!(mlayer_map & (1 << cur_mlayer_id))) continue;
7518
171
    const int tlayer_map = ops_mlayer_info->ops_tlayer_map[xLId][cur_mlayer_id];
7519
855
    for (int cur_tlayer_id = 0; cur_tlayer_id < MAX_NUM_TLAYERS;
7520
684
         cur_tlayer_id++) {
7521
1.71k
      for (int ref_tlayer_id = 0; ref_tlayer_id < cur_tlayer_id;
7522
1.02k
           ref_tlayer_id++) {
7523
1.02k
        if (seq_header->tlayer_dependency_map[cur_mlayer_id][cur_tlayer_id]
7524
1.02k
                                             [ref_tlayer_id] == 1) {
7525
0
          if ((tlayer_map & (1 << cur_tlayer_id)) &&
7526
0
              (tlayer_map & (1 << ref_tlayer_id)) == 0) {
7527
0
            avm_internal_error(
7528
0
                info, AVM_CODEC_UNSUP_BITSTREAM,
7529
0
                "Inconsistent tlayer dependency: In the activated sequence "
7530
0
                "header, tlayer_dependency_map[%d][%d][%d] is equal to 1, "
7531
0
                "indicating a tlayer with ID=%d depends on a tlayer with "
7532
0
                "ID=%d, while ops_tlayer_map[%d][%d] indicates that a tlayer "
7533
0
                "with ID=%d is not present.",
7534
0
                cur_mlayer_id, cur_tlayer_id, ref_tlayer_id, cur_tlayer_id,
7535
0
                ref_tlayer_id, xLId, cur_mlayer_id, ref_tlayer_id);
7536
0
          }
7537
0
        }
7538
1.02k
      }
7539
684
    }
7540
171
  }
7541
161
}
7542
7543
// This function calls check_ops_mlayer_tlayer_conformance function to perform
7544
// conformance checks accross the OPSes and xlayers present in the bitstream.
7545
static void check_ops_layer_map_conformance(struct AV2Decoder *pbi,
7546
2.97k
                                            const int xlayer_id) {
7547
2.97k
  AV2_COMMON *const cm = &pbi->common;
7548
2.97k
  struct SequenceHeader *const seq_header = &cm->seq_params;
7549
50.5k
  for (int ops_id = 0; ops_id < MAX_NUM_OPS_ID; ops_id++) {
7550
47.6k
    struct OperatingPointSet *ops = &pbi->ops_list[xlayer_id][ops_id];
7551
47.6k
    if (ops == NULL) continue;
7552
47.7k
    for (int i = 0; i < ops->ops_cnt; i++) {
7553
161
      OperatingPoint *op = &ops->op[i];
7554
161
      if (op == NULL) continue;
7555
161
      if (xlayer_id == GLOBAL_XLAYER_ID) {
7556
0
        for (int xLId = 0; xLId < MAX_NUM_XLAYERS - 1; xLId++) {
7557
0
          if ((op->ops_xlayer_map & (1 << xLId))) {
7558
0
            if (ops->ops_mlayer_info_idc == 1 ||
7559
0
                (ops->ops_mlayer_info_idc == 2 &&
7560
0
                 op->ops_mlayer_explicit_info_flag[xLId])) {
7561
0
              check_ops_mlayer_tlayer_conformance(seq_header, &op->mlayer_info,
7562
0
                                                  xLId, &cm->error);
7563
0
            }
7564
0
          }
7565
0
        }
7566
161
      } else {
7567
161
        check_ops_mlayer_tlayer_conformance(seq_header, &op->mlayer_info,
7568
161
                                            xlayer_id, &cm->error);
7569
161
      }
7570
161
    }
7571
47.6k
  }
7572
2.97k
}
7573
7574
2.95k
static void reset_qm_list(AV2Decoder *pbi) {
7575
2.95k
  AV2_COMMON *const cm = &pbi->common;
7576
  // reset QM to default: for both OLK and CLK
7577
2.95k
  const int num_planes = av2_num_planes(cm);
7578
47.2k
  for (int qm_pos = 0; qm_pos < NUM_CUSTOM_QMS; qm_pos++) {
7579
44.2k
    if ((pbi->obu_type == OBU_SWITCH || pbi->obu_type == OBU_RAS_FRAME) &&
7580
0
        pbi->qm_list[qm_pos].qm_mlayer_id != -1 &&
7581
0
        !is_mlayer_transitively_dependent(
7582
0
            &cm->seq_params, pbi->qm_list[qm_pos].qm_mlayer_id, cm->mlayer_id))
7583
0
      continue;
7584
7585
    // qm_protected[qm_pos] == 1 indicates the pbi->qm_list[qm_pos] is signalled
7586
    // with CLK/OLK. those quantizer matrices are not reset to the predefined.
7587
44.2k
    if (pbi->qm_protected[qm_pos]) continue;
7588
    // copy from predefined
7589
44.2k
    struct quantization_matrix_set *qmset = &pbi->qm_list[qm_pos];
7590
44.2k
    qmset->qm_id = qm_pos;
7591
44.2k
    qmset->qm_mlayer_id = -1;
7592
44.2k
    qmset->qm_tlayer_id = -1;
7593
44.2k
    qmset->quantizer_matrix_num_planes = num_planes;
7594
44.2k
    qmset->is_user_defined_qm = false;
7595
44.2k
  }
7596
2.95k
}
7597
7598
static void handle_sequence_header(AV2Decoder *pbi, OBU_TYPE obu_type,
7599
18.3k
                                   int xlayer_id, int seq_header_id) {
7600
18.3k
  AV2_COMMON *const cm = &pbi->common;
7601
18.3k
  bool keyframe_unit_in_tu =
7602
18.3k
      ((obu_type == OBU_CLOSED_LOOP_KEY || obu_type == OBU_OPEN_LOOP_KEY ||
7603
591
        obu_type == OBU_RAS_FRAME) &&
7604
17.7k
       pbi->this_is_first_vcl_obu_in_tu);
7605
7606
18.3k
  if (pbi->decoding_first_frame &&
7607
18.3k
      !(obu_type == OBU_CLOSED_LOOP_KEY || obu_type == OBU_OPEN_LOOP_KEY ||
7608
591
        obu_type == OBU_RAS_FRAME)) {
7609
591
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
7610
591
                       "the first frame of a bitstream shall be a keyframe");
7611
591
  }
7612
7613
18.3k
  struct SequenceHeader *seq_from_uch =
7614
18.3k
      &pbi->seq_list[xlayer_id][seq_header_id];
7615
7616
18.3k
  if (seq_from_uch->seq_header_id == -1) {
7617
59
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
7618
59
                       "No sequence header found with id = %d", seq_header_id);
7619
59
  }
7620
7621
18.3k
  if (seq_from_uch->sh_from_leading && !av2_is_leading_vcl_obu(obu_type)) {
7622
133
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7623
133
                       "Sequence header %d was signalled in a "
7624
133
                       "leading temporal unit and not re-signalled",
7625
133
                       seq_header_id);
7626
133
  }
7627
7628
  // SH activation
7629
18.3k
  if (keyframe_unit_in_tu &&
7630
2.97k
      (obu_type == OBU_CLOSED_LOOP_KEY ||
7631
2.97k
       (obu_type == OBU_OPEN_LOOP_KEY && pbi->random_accessed))) {
7632
2.97k
    pbi->active_seq[xlayer_id] = *seq_from_uch;
7633
    // Reset malyer_id_map
7634
26.7k
    for (int i = 0; i < MAX_NUM_MLAYERS; i++)
7635
23.8k
      pbi->mlayer_id_map[xlayer_id][i] = 0;
7636
    // Restore
7637
2.97k
    pbi->mlayer_id_map[xlayer_id][cm->mlayer_id] = 1;
7638
2.97k
  }
7639
7640
  // NOTE: cm->seq_params is a intermediate variable not to change the code too
7641
  // much
7642
18.3k
  cm->seq_params = pbi->active_seq[xlayer_id];
7643
7644
18.3k
  if (!keyframe_unit_in_tu) {
7645
14.5k
    if (!are_seq_headers_consistent(&cm->seq_params, seq_from_uch)) {
7646
1.00k
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
7647
1.00k
                         "Sequence Header changed at %s",
7648
1.00k
                         avm_obu_type_to_string(obu_type));
7649
1.00k
    }
7650
14.5k
  } else if (obu_type == OBU_OPEN_LOOP_KEY && !pbi->random_accessed) {
7651
0
    if (!are_seq_headers_consistent(&cm->seq_params, seq_from_uch)) {
7652
0
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
7653
0
                         "Sequence Header changed at OBU_OPEN_LOOP_KEY when "
7654
0
                         "pbi->random_accessed %d",
7655
0
                         pbi->random_accessed);
7656
0
      return;
7657
0
    }
7658
0
  }
7659
7660
  // check bitstream conformance if sequence header is parsed
7661
  // bitstream constraint for tlayer_id
7662
18.3k
  if (cm->tlayer_id > cm->seq_params.max_tlayer_id) {
7663
0
    avm_internal_error(
7664
0
        &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7665
0
        "Inconsistent tlayer_id information: OBU header indicates "
7666
0
        "tlayer_id is "
7667
0
        "%d, yet max_tlayer_id in the current active sequence header is %d.",
7668
0
        cm->tlayer_id, cm->seq_params.max_tlayer_id);
7669
0
  }
7670
  // bitstream constraint for mlayer_id
7671
18.3k
  if (cm->mlayer_id > cm->seq_params.max_mlayer_id) {
7672
0
    avm_internal_error(
7673
0
        &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7674
0
        "Inconsistent mlayer_id information: OBU header indicates "
7675
0
        "mlayer_id is "
7676
0
        "%d, yet max_mlayer_id in the sequence header is %d.",
7677
0
        cm->mlayer_id, cm->seq_params.max_mlayer_id);
7678
0
  }
7679
7680
18.3k
  if (!keyframe_unit_in_tu) {
7681
13.5k
    return;
7682
13.5k
  }
7683
7684
  // NOTE: at this point, the current obu is first CLK/OLK in the temporal unit
7685
  // cm->seq_params is the currently active sequence header
7686
18.3k
  assert(obu_type == OBU_CLOSED_LOOP_KEY || obu_type == OBU_OPEN_LOOP_KEY ||
7687
4.76k
         obu_type == OBU_RAS_FRAME);
7688
7689
  // Empty reference list
7690
  // NOTE: Should olk + random access reset reference list? It will be
7691
  // redundant but will it harm?
7692
4.76k
  if (obu_type == OBU_CLOSED_LOOP_KEY) {
7693
2.95k
    reset_ref_frame_map(cm);
7694
26.6k
    for (int layer = 0; layer < MAX_NUM_MLAYERS; layer++) {
7695
23.6k
      cm->olk_refresh_frame_flags[layer] = -1;
7696
23.6k
      cm->olk_co_vcl_refresh_frame_flags[layer] = -1;
7697
23.6k
      cm->prev_olk_co_vcl_refresh_frame_flags[layer] = -1;
7698
23.6k
    }
7699
2.95k
  }
7700
7701
  // When OBU_CONTENT_INTERPRETATION is not accompanied with the current obu
7702
  // at a RAP boundary, cm->ci_params_per_layer[cm->mlayer_id] is reset to
7703
  // default values and then inherited from a dependent layer.
7704
  // CI params are initialized at:
7705
  //   - All CLK frames
7706
  //   - OLK or RAS frames only when random access decoding starts at this TU
7707
  // For higher mlayers, the RAP boundary is inherited from transitively
7708
  // dependent layers that have a CLK, or an OLK/RAS with random access.
7709
4.76k
  const bool is_ci_present =
7710
4.76k
      pbi->obus_in_frame_unit_data[cm->tlayer_id][cm->mlayer_id]
7711
4.76k
                                  [OBU_CONTENT_INTERPRETATION];
7712
4.76k
  bool is_rap_boundary =
7713
4.76k
      (obu_type == OBU_CLOSED_LOOP_KEY) ||
7714
19
      ((obu_type == OBU_OPEN_LOOP_KEY || obu_type == OBU_RAS_FRAME) &&
7715
19
       pbi->random_accessed);
7716
4.76k
  if (!is_rap_boundary && cm->mlayer_id > 0) {
7717
0
    for (int ref = 0; ref < cm->mlayer_id; ref++) {
7718
0
      if (is_mlayer_transitively_dependent(&cm->seq_params, cm->mlayer_id,
7719
0
                                           ref) &&
7720
0
          (pbi->obus_in_frame_unit_data[cm->tlayer_id][ref]
7721
0
                                       [OBU_CLOSED_LOOP_KEY] ||
7722
0
           ((pbi->obus_in_frame_unit_data[cm->tlayer_id][ref]
7723
0
                                         [OBU_OPEN_LOOP_KEY] ||
7724
0
             pbi->obus_in_frame_unit_data[cm->tlayer_id][ref][OBU_RAS_FRAME]) &&
7725
0
            pbi->random_accessed))) {
7726
0
        is_rap_boundary = true;
7727
0
        break;
7728
0
      }
7729
0
    }
7730
0
  }
7731
4.76k
  if (!is_ci_present && is_rap_boundary) {
7732
    // Initialize to default first
7733
2.97k
    av2_initialize_ci_params(&cm->ci_params_per_layer[cm->mlayer_id]);
7734
7735
    // Then, inherit ci_params from the first transitively dependent layer
7736
2.97k
    for (int ref_layer_id = cm->mlayer_id - 1; ref_layer_id >= 0;
7737
2.97k
         ref_layer_id--) {
7738
0
      if (is_mlayer_transitively_dependent(&cm->seq_params, cm->mlayer_id,
7739
0
                                           ref_layer_id)) {
7740
0
        cm->ci_params_per_layer[cm->mlayer_id] =
7741
0
            cm->ci_params_per_layer[ref_layer_id];
7742
0
        break;
7743
0
      }
7744
0
    }
7745
2.97k
  }
7746
7747
  // check dependency map consistency for LCR
7748
4.76k
  check_lcr_layer_map_conformance(pbi, xlayer_id);
7749
  // check dependency map consistency for OPS
7750
4.76k
  check_ops_layer_map_conformance(pbi, xlayer_id);
7751
4.76k
}
7752
7753
static int is_reference_mapping_consistent(
7754
0
    int ref_list1[INTER_REFS_PER_FRAME], int ref_list2[INTER_REFS_PER_FRAME]) {
7755
0
  for (int i = 0; i < INTER_REFS_PER_FRAME; i++) {
7756
0
    if (ref_list1[i] != ref_list2[i]) {
7757
0
      return 0;
7758
0
    }
7759
0
  }
7760
0
  return 1;
7761
0
}
7762
7763
0
void update_num_restricted_ref(AV2_COMMON *const cm) {
7764
0
  int num_total_refs = cm->ref_frames_info.num_total_refs;
7765
0
  int num_restricted_ref = 0;
7766
0
  for (int i = 0; i < num_total_refs; i++) {
7767
0
    int dpb_idx = cm->remapped_ref_idx[i];
7768
0
    assert(cm->ref_frame_map[dpb_idx] != NULL);
7769
0
    if (cm->ref_frame_map[dpb_idx]->is_restricted) {
7770
0
      num_restricted_ref++;
7771
0
    }
7772
0
  }
7773
0
  cm->ref_frames_info.num_valid_refs_without_restricted_ref =
7774
0
      cm->ref_frames_info.num_total_refs - num_restricted_ref;
7775
0
  cm->ref_frames_info.num_valid_refs_with_restricted_ref =
7776
0
      cm->ref_frames_info.num_total_refs;
7777
0
  const int max_num_ref_frames =
7778
0
      AVMMIN(cm->seq_params.ref_frames, INTER_REFS_PER_FRAME);
7779
0
  if (cm->ref_frames_info.num_valid_refs_with_restricted_ref >
7780
0
      max_num_ref_frames)
7781
0
    cm->ref_frames_info.num_valid_refs_with_restricted_ref = max_num_ref_frames;
7782
0
}
7783
7784
// Called if the cm->cur_mfh_id is zero.
7785
16.5k
static void handle_zero_cur_mfh_id(AV2_COMMON *const cm) {
7786
16.5k
  const SequenceHeader *const seq_params = &cm->seq_params;
7787
16.5k
  cm->mfh_params[cm->cur_mfh_id].mfh_frame_width = seq_params->max_frame_width;
7788
16.5k
  cm->mfh_params[cm->cur_mfh_id].mfh_frame_height =
7789
16.5k
      seq_params->max_frame_height;
7790
16.5k
  cm->mfh_params[cm->cur_mfh_id].mfh_deblocking_filter_update_flag = 0;
7791
82.6k
  for (int i = 0; i < 4; i++) {
7792
66.1k
    cm->mfh_params[cm->cur_mfh_id].mfh_apply_deblocking_filter[i] = 0;
7793
66.1k
  }
7794
16.5k
  cm->mfh_params[cm->cur_mfh_id].mfh_mlayer_id = cm->mlayer_id;
7795
16.5k
  cm->mfh_params[cm->cur_mfh_id].mfh_tlayer_id = cm->tlayer_id;
7796
16.5k
  cm->mfh_valid[cm->cur_mfh_id] = true;
7797
16.5k
}
7798
7799
static int setup_multiframe_header_id(AV2_COMMON *const cm, OBU_TYPE obu_type,
7800
18.3k
                                      struct avm_read_bit_buffer *rb) {
7801
18.3k
  uint32_t cur_mfh_id = obu_type == OBU_BRIDGE_FRAME ? 0 : avm_rb_read_uvlc(rb);
7802
18.3k
  if (cur_mfh_id >= MAX_MFH_NUM) {
7803
2
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
7804
2
                       "multi-frame header id is greater than or equal to "
7805
2
                       "the maximum multi-frame header number");
7806
2
  }
7807
18.3k
  return cur_mfh_id;
7808
18.3k
}
7809
7810
static int setup_sequence_header_id(AV2_COMMON *const cm,
7811
18.3k
                                    struct avm_read_bit_buffer *rb) {
7812
18.3k
  int seq_header_id_in_frame_header = -1;
7813
18.3k
  if (cm->cur_mfh_id == 0) {
7814
18.3k
    seq_header_id_in_frame_header = avm_rb_read_uvlc(rb);
7815
18.3k
    if (seq_header_id_in_frame_header >= MAX_SEQ_NUM) {
7816
5
      avm_internal_error(
7817
5
          &cm->error, AVM_CODEC_CORRUPT_FRAME,
7818
5
          "Unsupported Sequence Header ID in uncompressed_header()");
7819
5
    }
7820
18.3k
    cm->mfh_params[cm->cur_mfh_id].mfh_seq_header_id =
7821
18.3k
        (int)seq_header_id_in_frame_header;
7822
18.3k
  } else {
7823
56
    if (!cm->mfh_valid[cm->cur_mfh_id]) {
7824
56
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
7825
56
                         "No multi-frame header with mfh_id %d",
7826
56
                         cm->cur_mfh_id);
7827
56
    }
7828
56
    seq_header_id_in_frame_header =
7829
56
        cm->mfh_params[cm->cur_mfh_id].mfh_seq_header_id;
7830
56
  }
7831
7832
18.3k
  return seq_header_id_in_frame_header;
7833
18.3k
}
7834
7835
static int av1_get_obu_trailing_bits_count(const uint8_t *obu_payload,
7836
21.8k
                                           size_t payload_size) {
7837
21.8k
  assert(payload_size != 0);
7838
7839
21.8k
  int trailing_bits = 0;
7840
7841
  // Step 1: Get the last nonzero byte of the payload
7842
21.8k
  int i;
7843
23.2k
  for (i = (int)payload_size - 1; i >= 0; i--) {
7844
23.2k
    if (obu_payload[i] != 0) {
7845
21.8k
      break;
7846
21.8k
    }
7847
1.38k
    trailing_bits += 8;
7848
1.38k
  }
7849
7850
  // Step 2: If all bytes are 0, then is invalid: there should be at least 1
7851
21.8k
  if (i < 0) return -1;
7852
7853
  // Step 3: Read backwards from bit 0 to find the first one
7854
21.8k
  uint8_t last_nonzero_byte = obu_payload[i];
7855
24.9k
  for (int bit_pos = 0; bit_pos < 8; bit_pos++) {
7856
24.9k
    if (last_nonzero_byte & (1 << bit_pos)) {
7857
      // Found the trailing "1" bit marker
7858
21.8k
      trailing_bits += bit_pos + 1;
7859
21.8k
      break;
7860
21.8k
    }
7861
24.9k
  }
7862
21.8k
  return trailing_bits;
7863
21.8k
}
7864
7865
int read_obu_extension_bits(const uint8_t *obu_payload, size_t payload_size,
7866
                            size_t bits_read_before_extension,
7867
21.8k
                            struct avm_internal_error_info *error_info) {
7868
  // Get trailing bits count
7869
21.8k
  int num_trailing_bits =
7870
21.8k
      av1_get_obu_trailing_bits_count(obu_payload, payload_size);
7871
21.8k
  if (num_trailing_bits < 0) {
7872
0
    avm_internal_error(
7873
0
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
7874
0
        "Trailing bits are not found when OBU extension data is present.");
7875
0
  }
7876
7877
  // Calculate total bits in payload
7878
21.8k
  size_t total_payload_bits = payload_size * 8;
7879
7880
  // Extension data bits = total - bits_read_before_extension -1 (ext flag) -
7881
  // trailing bits
7882
21.8k
  if (total_payload_bits - bits_read_before_extension - 1 <
7883
21.8k
      (size_t)num_trailing_bits) {
7884
1
    avm_internal_error(
7885
1
        error_info, AVM_CODEC_UNSUP_BITSTREAM,
7886
1
        "Trailing bits are not found when OBU extension data is present.");
7887
1
  }
7888
21.8k
  size_t extension_data_bits =
7889
21.8k
      total_payload_bits - bits_read_before_extension - 1 - num_trailing_bits;
7890
7891
21.8k
  return (int)extension_data_bits;
7892
21.8k
}
7893
7894
// On success, returns 0. On failure, calls avm_internal_error and does not
7895
// return.
7896
static int read_uncompressed_header(AV2Decoder *pbi, OBU_TYPE obu_type,
7897
                                    int obu_xlayer_id,
7898
18.3k
                                    struct avm_read_bit_buffer *rb) {
7899
18.3k
  AV2_COMMON *const cm = &pbi->common;
7900
18.3k
  const SequenceHeader *const seq_params = &cm->seq_params;
7901
18.3k
  const ContentInterpretation *const ci_params =
7902
18.3k
      &cm->ci_params_per_layer[cm->mlayer_id];
7903
18.3k
  const ColorInfo *const color_info = &ci_params->color_info;
7904
18.3k
  CurrentFrame *const current_frame = &cm->current_frame;
7905
18.3k
  FeatureFlags *const features = &cm->features;
7906
18.3k
  MACROBLOCKD *const xd = &pbi->dcb.xd;
7907
18.3k
  BufferPool *const pool = cm->buffer_pool;
7908
18.3k
  avm_s_frame_info *sframe_info = &pbi->sframe_info;
7909
18.3k
  init_bru_params(cm);
7910
#if CONFIG_PARAKIT_COLLECT_DATA
7911
  for (int i = 0; i < MAX_NUM_CTX_GROUPS; i++) {
7912
    cm->prob_models[i].frameNumber = current_frame->frame_number;
7913
    cm->prob_models[i].frameType = current_frame->frame_type;
7914
    for (int j = 0; j < MAX_DIMS_CONTEXT3; j++)
7915
      for (int k = 0; k < MAX_DIMS_CONTEXT2; k++)
7916
        for (int l = 0; l < MAX_DIMS_CONTEXT1; l++)
7917
          for (int h = 0; h < MAX_DIMS_CONTEXT0; h++)
7918
            beginningFrameFlag[i][j][k][l][h] = 1;
7919
  }
7920
#endif
7921
7922
18.3k
  cm->cur_mfh_id = setup_multiframe_header_id(cm, obu_type, rb);
7923
7924
18.3k
  int seq_header_id_for_frame_header = setup_sequence_header_id(cm, rb);
7925
18.3k
  assert(seq_header_id_for_frame_header >= 0);
7926
7927
18.3k
  handle_sequence_header(pbi, obu_type, obu_xlayer_id,
7928
18.3k
                         seq_header_id_for_frame_header);
7929
7930
18.3k
  if (cm->cur_mfh_id == 0) {
7931
16.5k
    handle_zero_cur_mfh_id(cm);
7932
16.5k
  } else {
7933
    // Validate MFH frame dimensions when a MFH is present
7934
1.85k
    assert(cm->mfh_valid[cm->cur_mfh_id]);
7935
1.85k
    const MultiFrameHeader *mfh_param = &cm->mfh_params[cm->cur_mfh_id];
7936
1.85k
    if (mfh_param->mfh_frame_size_present_flag) {
7937
0
      if (mfh_param->mfh_frame_width > seq_params->max_frame_width ||
7938
0
          mfh_param->mfh_frame_height > seq_params->max_frame_height) {
7939
0
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
7940
0
                           "MFH frame dimensions are larger than the sequence "
7941
0
                           "header values.\n");
7942
0
      }
7943
0
    }
7944
    // Check conformance for MFH according to dependency maps
7945
1.85k
    const int ref_mfh_mlayer_id = cm->mfh_params[cm->cur_mfh_id].mfh_mlayer_id;
7946
1.85k
    const int ref_mfh_tlayer_id = cm->mfh_params[cm->cur_mfh_id].mfh_tlayer_id;
7947
1.85k
    if (!seq_params->mlayer_dependency_map[cm->mlayer_id][ref_mfh_mlayer_id] ||
7948
0
        !seq_params->tlayer_dependency_map[cm->mlayer_id][cm->tlayer_id]
7949
0
                                          [ref_mfh_tlayer_id]) {
7950
0
      avm_internal_error(
7951
0
          &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7952
0
          "The MFH selection for the current layer with mlayer_id=%d, "
7953
0
          "tlayer_id=%d shall not depend on the MFH with mlayer_id=%d, "
7954
0
          "tlayer_id=%d according to the layer dependency maps.",
7955
0
          cm->mlayer_id, cm->tlayer_id, ref_mfh_mlayer_id, ref_mfh_tlayer_id);
7956
0
    }
7957
1.85k
  }
7958
7959
18.3k
  if (obu_type == OBU_RAS_FRAME &&
7960
0
      seq_params->number_of_bits_for_lt_frame_id == 0) {
7961
0
    avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7962
0
                       "no OBU_RAS_FRAME shall be present when "
7963
0
                       "number_of_bits_for_lt_frame_id == 0");
7964
0
  }
7965
7966
18.3k
  if (obu_type == OBU_BRIDGE_FRAME) {
7967
0
    cm->bridge_frame_info.is_bridge_frame = 1;
7968
0
    const int bridge_frame_ref_idx =
7969
0
        avm_rb_read_literal(rb, seq_params->ref_frames_log2);
7970
7971
    // Check reference is valid.
7972
0
    if (bridge_frame_ref_idx >= seq_params->ref_frames) {
7973
0
      avm_internal_error(
7974
0
          &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7975
0
          "Bridge frame ref idx must be less than %d but is set to %d",
7976
0
          seq_params->ref_frames, bridge_frame_ref_idx);
7977
0
    }
7978
0
    RefCntBuffer *const bridge_frame_ref =
7979
0
        cm->ref_frame_map[bridge_frame_ref_idx];
7980
0
    if (bridge_frame_ref == NULL) {
7981
0
      avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
7982
0
                         "Buffer does not contain a decoded frame");
7983
0
    }
7984
0
    cm->bridge_frame_info.bridge_frame_ref_idx = bridge_frame_ref_idx;
7985
18.3k
  } else {
7986
18.3k
    cm->bridge_frame_info.is_bridge_frame = 0;
7987
18.3k
    cm->bridge_frame_info.bridge_frame_ref_idx = INVALID_IDX;
7988
18.3k
  }
7989
7990
18.3k
  if (obu_type == OBU_OPEN_LOOP_KEY || obu_type == OBU_CLOSED_LOOP_KEY) {
7991
16.5k
    if (seq_params->seq_lcr_id != LCR_ID_UNSPECIFIED) {
7992
45
      activate_layer_configuration_record(pbi, seq_params->seq_lcr_id);
7993
16.4k
    } else {
7994
16.4k
      memset(&cm->lcr_params, 0, sizeof(struct LayerConfigurationRecord));
7995
16.4k
      memset(&cm->atlas_params, 0, sizeof(struct AtlasSegmentInfo));
7996
16.4k
    }
7997
16.5k
  }
7998
7999
18.3k
  if (color_info->matrix_coefficients == AVM_CICP_MC_IDENTITY &&
8000
0
      (seq_params->subsampling_x || seq_params->subsampling_y)) {
8001
0
    avm_internal_error(
8002
0
        &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8003
0
        "Matrix coefficients incompatible with non 4:4:4 color sampling.");
8004
0
  }
8005
8006
18.3k
  if (seq_params->single_picture_header_flag) {
8007
16.4k
    cm->show_existing_frame = 0;
8008
16.4k
    cm->immediate_output_picture = 1;
8009
16.4k
    cm->implicit_output_picture = 0;
8010
16.4k
    cm->cur_frame->immediate_output_picture = 1;
8011
16.4k
    cm->cur_frame->implicit_output_picture = 0;
8012
16.4k
    if (obu_type != OBU_CLOSED_LOOP_KEY) {
8013
34
      avm_internal_error(
8014
34
          &cm->error, AVM_CODEC_CORRUPT_FRAME,
8015
34
          "Still pictures must be coded as closed loop keyframes");
8016
34
    }
8017
16.4k
    current_frame->frame_type = KEY_FRAME;
8018
16.4k
    pbi->decoding_first_frame = 1;
8019
16.4k
    reset_frame_buffers(cm);
8020
16.4k
    cm->cur_frame->frame_output_done = 0;
8021
16.4k
    if (pbi->this_is_first_vcl_obu_in_tu) reset_qm_list(pbi);
8022
16.4k
  } else {
8023
1.91k
    pbi->reset_decoder_state = 0;
8024
1.91k
    cm->show_existing_frame = 0;
8025
1.91k
    if (obu_type == OBU_LEADING_SEF || obu_type == OBU_REGULAR_SEF)
8026
0
      return read_show_existing_frame(pbi, obu_type == OBU_REGULAR_SEF, rb);
8027
1.91k
    if (obu_type == OBU_CLOSED_LOOP_KEY || obu_type == OBU_OPEN_LOOP_KEY) {
8028
17
      current_frame->frame_type = KEY_FRAME;
8029
17
      if (pbi->this_is_first_vcl_obu_in_tu) reset_qm_list(pbi);
8030
1.89k
    } else if (obu_type == OBU_RAS_FRAME || obu_type == OBU_SWITCH) {
8031
0
      current_frame->frame_type = S_FRAME;
8032
0
      cm->restricted_prediction_switch = avm_rb_read_bit(rb);
8033
0
      if (cm->restricted_prediction_switch) {
8034
0
        for (int i = 0; i < REF_FRAMES; i++) {
8035
0
          if (cm->ref_frame_map[i] != NULL) {
8036
0
            if (is_mlayer_transitively_dependent(
8037
0
                    &cm->seq_params, cm->ref_frame_map[i]->mlayer_id,
8038
0
                    cm->mlayer_id)) {
8039
0
              if (is_frame_eligible_for_output(cm->ref_frame_map[i])) {
8040
0
                const int doh_error = av2_output_frame_buffers(pbi, i);
8041
0
                if (doh_error) {
8042
0
                  avm_internal_error(
8043
0
                      &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8044
0
                      "Display order hint of an output picture is not unique"
8045
0
                      " in the same (xlayer_id %d) layer.",
8046
0
                      cm->xlayer_id);
8047
0
                }
8048
0
              }
8049
0
              cm->ref_frame_map[i]->is_restricted = true;
8050
0
              cm->ref_frame_map[i]->display_order_hint = REF_RESTRICTED_DOH;
8051
0
            }
8052
0
          }
8053
0
        }
8054
8055
        // A restricted switch frame resets the DOH epoch for this layer.
8056
        // This marks a CVS-internal epoch boundary where DOH derivation is
8057
        // restarted.
8058
0
        for (int ml = 0; ml <= cm->seq_params.max_mlayer_id; ml++) {
8059
0
          if (is_mlayer_transitively_dependent(&cm->seq_params, ml,
8060
0
                                               cm->mlayer_id)) {
8061
0
            pbi->last_output_doh[cm->xlayer_id][ml] = -1;
8062
0
          }
8063
0
        }
8064
0
        memset(&pbi->last_frame_unit, -1, sizeof(pbi->last_frame_unit));
8065
0
        memset(&pbi->last_displayable_frame_unit, -1,
8066
0
               sizeof(pbi->last_displayable_frame_unit));
8067
0
      }
8068
0
      if (obu_type == OBU_RAS_FRAME || cm->restricted_prediction_switch)
8069
0
        reset_qm_list(pbi);
8070
1.89k
    } else if (obu_type == OBU_REGULAR_TIP || obu_type == OBU_LEADING_TIP ||
8071
0
               cm->bridge_frame_info.is_bridge_frame) {
8072
0
      current_frame->frame_type = INTER_FRAME;
8073
1.89k
    } else {
8074
1.89k
      current_frame->frame_type =
8075
1.89k
          avm_rb_read_bit(rb) ? INTER_FRAME : INTRA_ONLY_FRAME;
8076
1.89k
    }
8077
1.91k
    current_frame->long_term_id = -1;
8078
1.91k
    if (current_frame->frame_type == KEY_FRAME) {
8079
17
      const int long_term_id_plus_1 =
8080
17
          avm_rb_read_literal(rb, seq_params->number_of_bits_for_lt_frame_id);
8081
17
      current_frame->long_term_id = long_term_id_plus_1 - 1;
8082
17
    }
8083
8084
1.91k
    if (obu_type == OBU_RAS_FRAME || obu_type == OBU_OPEN_LOOP_KEY) {
8085
1
      cm->num_ref_key_frames = 0;
8086
1
      if (seq_params->number_of_bits_for_lt_frame_id != 0) {
8087
0
        cm->num_ref_key_frames = avm_rb_read_literal(rb, 3);
8088
0
        for (int i = 0; i < cm->num_ref_key_frames; i++) {
8089
0
          cm->ref_long_term_ids[i] = avm_rb_read_literal(
8090
0
              rb, seq_params->number_of_bits_for_lt_frame_id);
8091
0
        }
8092
0
      }
8093
1
    }
8094
8095
1.91k
    if (cm->bridge_frame_info.is_bridge_frame) {
8096
0
      cm->immediate_output_picture = 0;
8097
1.91k
    } else {
8098
1.91k
      if (obu_type == OBU_OPEN_LOOP_KEY)
8099
1
        cm->immediate_output_picture = 0;
8100
1.91k
      else
8101
1.91k
        cm->immediate_output_picture = avm_rb_read_bit(rb);
8102
1.91k
    }
8103
8104
1.91k
    if (cm->immediate_output_picture == 0) pbi->is_arf_frame_present = 1;
8105
1.91k
    if (obu_type == OBU_OPEN_LOOP_KEY) pbi->is_fwd_kf_present = 1;
8106
1.91k
    if (cm->current_frame.frame_type == S_FRAME) {
8107
0
      sframe_info->is_s_frame = 1;
8108
0
      sframe_info->is_s_frame_at_altref = cm->immediate_output_picture ? 0 : 1;
8109
0
    }
8110
1.91k
    if (seq_params->still_picture && (current_frame->frame_type != KEY_FRAME ||
8111
1
                                      !cm->immediate_output_picture)) {
8112
0
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
8113
0
                         "Still pictures must be coded as shown keyframes");
8114
0
    }
8115
1.91k
    if (!cm->immediate_output_picture) {
8116
1
      if (cm->bridge_frame_info.is_bridge_frame) {
8117
0
        cm->implicit_output_picture = 0;
8118
1
      } else if (!seq_params->monotonic_output_order_flag) {
8119
1
        cm->implicit_output_picture = avm_rb_read_bit(rb);
8120
1
      } else {
8121
0
        cm->implicit_output_picture = 0;
8122
0
      }
8123
1.91k
    } else {
8124
1.91k
      cm->implicit_output_picture = 0;
8125
1.91k
    }
8126
8127
1.91k
    cm->cur_frame->immediate_output_picture = cm->immediate_output_picture;
8128
1.91k
    cm->cur_frame->implicit_output_picture = cm->implicit_output_picture;
8129
1.91k
    cm->cur_frame->frame_output_done = 0;
8130
1.91k
  }
8131
18.3k
  av2_set_frame_sb_size(cm, cm->seq_params.sb_size);
8132
8133
18.3k
  int frame_size_override_flag = 0;
8134
18.3k
  features->allow_intrabc = 0;
8135
18.3k
  features->allow_global_intrabc = 0;
8136
18.3k
  features->allow_local_intrabc = 0;
8137
18.3k
  features->primary_ref_frame = PRIMARY_REF_NONE;
8138
8139
18.3k
  int signal_primary_ref_frame = -1;
8140
18.3k
  features->derived_primary_ref_frame = PRIMARY_REF_NONE;
8141
18.3k
  pbi->signal_primary_ref_frame = -1;
8142
8143
18.3k
  features->cross_frame_context = CROSS_FRAME_CONTEXT_FORWARD;
8144
8145
18.3k
  if (!seq_params->single_picture_header_flag) {
8146
17
    if (obu_type == OBU_CLOSED_LOOP_KEY) {
8147
16
      pbi->olk_encountered = 0;
8148
16
    } else if (obu_type == OBU_OPEN_LOOP_KEY) {
8149
1
      if (pbi->olk_encountered && pbi->this_is_first_vcl_obu_in_tu) {
8150
        // This is the case when the first regular frame is another OLK
8151
        // (0-4(K)-2-1-3-8(K)...
8152
0
        lock_buffer_pool(pool);
8153
0
        reset_buffer_other_than_OLK(pbi);
8154
0
        unlock_buffer_pool(pool);
8155
0
      }
8156
1
      pbi->olk_encountered = 1;
8157
1
    } else if (pbi->olk_encountered && av2_is_regular_non_olk_obu(obu_type) &&
8158
0
               pbi->this_is_first_vcl_obu_in_tu) {
8159
0
      lock_buffer_pool(pool);
8160
0
      reset_buffer_other_than_OLK(pbi);
8161
0
      unlock_buffer_pool(pool);
8162
0
      pbi->olk_encountered = 0;
8163
0
    }
8164
17
    if (cm->bridge_frame_info.is_bridge_frame) {
8165
0
      frame_size_override_flag = 1;
8166
17
    } else {
8167
17
      frame_size_override_flag = frame_is_sframe(cm) ? 1 : avm_rb_read_bit(rb);
8168
17
      current_frame->order_hint = avm_rb_read_literal(
8169
17
          rb, seq_params->order_hint_info.order_hint_bits_minus_1 + 1);
8170
17
      current_frame->display_order_hint = get_disp_order_hint(
8171
17
          cm, obu_type, pbi->random_accessed, false, -1, -1);
8172
17
      check_consistent_disp_order_hint_derivation(pbi, obu_type,
8173
17
                                                  pbi->random_accessed);
8174
17
      current_frame->frame_number = current_frame->order_hint;
8175
17
      current_frame->display_order_hint_restricted =
8176
17
          current_frame->display_order_hint;
8177
8178
      // Conformance (7.4.4): if long_term_frame_id_bits is greater than 0, the
8179
      // OrderHint of an OLK shall be less than (1 << OrderHintBits).
8180
17
      if (obu_type == OBU_OPEN_LOOP_KEY &&
8181
1
          seq_params->number_of_bits_for_lt_frame_id > 0 &&
8182
0
          current_frame->display_order_hint >=
8183
0
              (1u << (seq_params->order_hint_info.order_hint_bits_minus_1 +
8184
0
                      1))) {
8185
0
        avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8186
0
                           "OrderHint of an OLK must be less than "
8187
0
                           "(1 << OrderHintBits) when "
8188
0
                           "long_term_frame_id_bits is greater than 0");
8189
0
      }
8190
8191
      // Conformance (7.4.4): if long_term_frame_id_bits is greater than 0, the
8192
      // OrderHint of a RAS frame with restricted_prediction_switch equal to 0
8193
      // shall be less than (1 << OrderHintBits).
8194
17
      if (obu_type == OBU_RAS_FRAME && !cm->restricted_prediction_switch &&
8195
0
          seq_params->number_of_bits_for_lt_frame_id > 0 &&
8196
0
          current_frame->display_order_hint >=
8197
0
              (1u << (seq_params->order_hint_info.order_hint_bits_minus_1 +
8198
0
                      1))) {
8199
0
        avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8200
0
                           "OrderHint of a RAS frame with "
8201
0
                           "restricted_prediction_switch equal to 0 must be "
8202
0
                           "less than (1 << OrderHintBits) when "
8203
0
                           "long_term_frame_id_bits is greater than 0");
8204
0
      }
8205
8206
      // DOH constraint checks
8207
17
      const int msdo_doh = pbi->common.msdo_params.msdo_doh_constraint_flag;
8208
17
      const int lcr_doh =
8209
17
          (pbi->active_lcr != NULL && pbi->active_lcr->is_global &&
8210
0
           pbi->active_lcr->global_lcr.lcr_doh_constraint_flag);
8211
8212
      // Conformance: when monotonic_output_order_flag is 0 in any activated
8213
      // sequence header, msdo_doh_constraint_flag shall be 1.
8214
      // Only applies when an MSDO OBU is present (multistream decoder mode).
8215
      // The equivalent lcr_doh_constraint_flag check is in
8216
      // av2_decode_frame_headers_obu() at LCR activation time.
8217
17
      if (pbi->multistream_decoder_mode &&
8218
13
          !seq_params->monotonic_output_order_flag && !msdo_doh) {
8219
9
        avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8220
9
                           "msdo_doh_constraint_flag must be 1 when "
8221
9
                           "monotonic_output_order_flag is 0");
8222
9
      }
8223
8224
17
      const int doh_active = (msdo_doh || lcr_doh);
8225
17
      if (doh_active) {
8226
4
        const int order_hint_bits =
8227
4
            seq_params->order_hint_info.order_hint_bits_minus_1 + 1;
8228
8229
        // All pictures in a TU must use the same OrderHintBits
8230
4
        if (!pbi->doh_tu_order_hint_bits_set) {
8231
1
          pbi->doh_tu_order_hint_bits = order_hint_bits;
8232
1
          pbi->doh_tu_order_hint_bits_set = 1;
8233
3
        } else if (pbi->doh_tu_order_hint_bits != order_hint_bits) {
8234
0
          avm_internal_error(
8235
0
              &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8236
0
              "DOH constraint: all pictures in a TU must use the same "
8237
0
              "OrderHintBits");
8238
0
        }
8239
4
      }
8240
17
    }
8241
8242
17
    if (obu_type == OBU_OPEN_LOOP_KEY) {
8243
1
      if (cm->implicit_output_picture) {
8244
1
        pbi->last_olk_tu_display_order_hint = current_frame->display_order_hint;
8245
1
      } else {
8246
        // prevent resetting it to -1 when {OLK(s) - OLK(h)} when a hidden OLK
8247
        // comes after a shown OLK
8248
0
        if (pbi->this_is_first_vcl_obu_in_tu ||
8249
0
            pbi->last_olk_tu_display_order_hint == -1) {
8250
0
          pbi->last_olk_tu_display_order_hint = -1;
8251
0
        }
8252
0
      }
8253
16
    } else if (pbi->olk_encountered && av2_is_regular_non_olk_obu(obu_type)) {
8254
0
      if (pbi->last_olk_tu_display_order_hint == -1 &&
8255
0
          !pbi->this_is_first_vcl_obu_in_tu &&
8256
0
          (cm->implicit_output_picture || cm->immediate_output_picture)) {
8257
        // regular frame in the same temporal unit with a hidden olk
8258
0
        pbi->last_olk_tu_display_order_hint = current_frame->display_order_hint;
8259
0
      }
8260
0
    }
8261
8262
17
    if (!frame_is_sframe(cm) && !frame_is_intra_only(cm)) {
8263
0
      if (!cm->bridge_frame_info.is_bridge_frame) {
8264
0
        signal_primary_ref_frame = avm_rb_read_bit(rb);
8265
0
        if (obu_type != OBU_REGULAR_TIP && obu_type != OBU_LEADING_TIP)
8266
0
          features->cross_frame_context = avm_rb_read_bit(rb)
8267
0
                                              ? CROSS_FRAME_CONTEXT_DISABLED
8268
0
                                              : CROSS_FRAME_CONTEXT_FORWARD;
8269
0
        pbi->signal_primary_ref_frame = signal_primary_ref_frame;
8270
0
        if (signal_primary_ref_frame) {
8271
0
          features->primary_ref_frame =
8272
0
              avm_rb_read_literal(rb, PRIMARY_REF_BITS);
8273
0
          features->derived_primary_ref_frame = features->primary_ref_frame;
8274
0
        }
8275
0
      }
8276
0
    }
8277
17
  }
8278
8279
18.3k
  if (obu_type == OBU_CLOSED_LOOP_KEY || obu_type == OBU_OPEN_LOOP_KEY) {
8280
16.4k
    if (obu_type == OBU_CLOSED_LOOP_KEY && seq_params->max_mlayer_id == 0) {
8281
16.4k
      current_frame->refresh_frame_flags = ((1 << seq_params->ref_frames) - 1);
8282
16.4k
    } else if (obu_type == OBU_OPEN_LOOP_KEY ||
8283
2
               seq_params->max_mlayer_id != 0) {
8284
2
      const int short_refresh_frame_flags =
8285
2
          cm->seq_params.enable_short_refresh_frame_flags;
8286
2
      const int refresh_frame_flags_bits = short_refresh_frame_flags
8287
2
                                               ? seq_params->ref_frames_log2
8288
2
                                               : seq_params->ref_frames;
8289
8290
2
      if (short_refresh_frame_flags) {
8291
0
        const int refresh_idx =
8292
0
            avm_rb_read_literal(rb, refresh_frame_flags_bits);
8293
0
        current_frame->refresh_frame_flags = 1 << refresh_idx;
8294
2
      } else {
8295
2
        current_frame->refresh_frame_flags =
8296
2
            avm_rb_read_literal(rb, refresh_frame_flags_bits);
8297
2
      }
8298
2
    }
8299
16.4k
    if (obu_type == OBU_CLOSED_LOOP_KEY && pbi->this_is_first_vcl_obu_in_tu) {
8300
8.85k
      for (int ref_pos = 0; ref_pos < seq_params->ref_frames; ref_pos++) {
8301
5.90k
        if (!(current_frame->refresh_frame_flags >> ref_pos & 1u)) {
8302
16
          decrease_ref_count(cm->ref_frame_map[ref_pos], pool);
8303
16
          cm->ref_frame_map[ref_pos] = NULL;
8304
16
        }
8305
5.90k
      }
8306
2.95k
    }
8307
16.4k
    if (obu_type == OBU_OPEN_LOOP_KEY) {
8308
1
      cm->olk_refresh_frame_flags[cm->mlayer_id] =
8309
1
          current_frame->refresh_frame_flags;
8310
1
    }
8311
131k
    for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
8312
115k
      cm->remapped_ref_idx[i] = INVALID_IDX;
8313
115k
    }
8314
16.4k
    if (pbi->need_resync) {
8315
16.4k
      reset_ref_frame_map(cm);
8316
16.4k
      pbi->need_resync = 0;
8317
16.4k
    }
8318
16.4k
  } else {
8319
1.94k
    const int short_refresh_frame_flags =
8320
1.94k
        cm->seq_params.enable_short_refresh_frame_flags && !frame_is_sframe(cm);
8321
1.94k
    const int refresh_frame_flags_bits = short_refresh_frame_flags
8322
1.94k
                                             ? seq_params->ref_frames_log2
8323
1.94k
                                             : seq_params->ref_frames;
8324
8325
1.94k
    if (current_frame->frame_type == INTRA_ONLY_FRAME) {
8326
0
      if (short_refresh_frame_flags) {
8327
0
        const bool has_refresh_frame_flags = avm_rb_read_bit(rb);
8328
0
        if (has_refresh_frame_flags) {
8329
0
          const int refresh_idx =
8330
0
              avm_rb_read_literal(rb, refresh_frame_flags_bits);
8331
0
          if (refresh_idx >= seq_params->ref_frames) {
8332
0
            avm_internal_error(
8333
0
                &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8334
0
                "refresh_idx must be less than %d but is set to %d",
8335
0
                seq_params->ref_frames, refresh_idx);
8336
0
          }
8337
0
          current_frame->refresh_frame_flags = 1 << refresh_idx;
8338
0
        } else {
8339
0
          current_frame->refresh_frame_flags = 0;
8340
0
        }
8341
0
      } else {
8342
0
        current_frame->refresh_frame_flags =
8343
0
            avm_rb_read_literal(rb, refresh_frame_flags_bits);
8344
0
      }
8345
0
      assert(seq_params->ref_frames >= 1);
8346
0
      if (seq_params->ref_frames > 1 &&
8347
0
          current_frame->refresh_frame_flags ==
8348
0
              ((1 << seq_params->ref_frames) - 1)) {
8349
0
        avm_internal_error(
8350
0
            &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8351
0
            "Intra only frames cannot refresh all the available entries in "
8352
0
            "the decoded picture buffer (DPB) if the DPB size is larger than "
8353
0
            "1. A key-frame should be inserted to refresh all entries.");
8354
0
      }
8355
0
      if (pbi->need_resync) {
8356
0
        reset_ref_frame_map(cm);
8357
0
        pbi->need_resync = 0;
8358
0
      }
8359
1.94k
    } else if (pbi->need_resync != 1) { /* Skip if need resync */
8360
0
      if (pbi->obu_type == OBU_RAS_FRAME && seq_params->max_mlayer_id == 0) {
8361
0
        current_frame->refresh_frame_flags =
8362
0
            ras_frame_refresh_frame_flags_derivation(pbi);
8363
0
      } else if (frame_is_sframe(cm)) {
8364
0
        current_frame->refresh_frame_flags =
8365
0
            avm_rb_read_literal(rb, seq_params->ref_frames);
8366
0
      } else {
8367
0
        if (cm->bridge_frame_info.is_bridge_frame) {
8368
0
          cm->bridge_frame_info.bridge_frame_overwrite_flag =
8369
0
              avm_rb_read_bit(rb);
8370
0
          if (!cm->bridge_frame_info.bridge_frame_overwrite_flag) {
8371
0
            current_frame->refresh_frame_flags =
8372
0
                1 << cm->bridge_frame_info.bridge_frame_ref_idx;
8373
0
          }
8374
0
        }
8375
8376
0
        if (!cm->bridge_frame_info.is_bridge_frame ||
8377
0
            cm->bridge_frame_info.bridge_frame_overwrite_flag) {
8378
0
          if (short_refresh_frame_flags) {
8379
0
            const bool has_refresh_frame_flags = avm_rb_read_bit(rb);
8380
0
            if (has_refresh_frame_flags) {
8381
0
              const int refresh_idx =
8382
0
                  avm_rb_read_literal(rb, refresh_frame_flags_bits);
8383
0
              if (refresh_idx >= seq_params->ref_frames) {
8384
0
                avm_internal_error(
8385
0
                    &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8386
0
                    "refresh_idx must be less than %d but is set to %d",
8387
0
                    seq_params->ref_frames, refresh_idx);
8388
0
              }
8389
0
              current_frame->refresh_frame_flags = 1 << refresh_idx;
8390
0
            } else {
8391
0
              current_frame->refresh_frame_flags = 0;
8392
0
            }
8393
0
          } else {
8394
0
            current_frame->refresh_frame_flags =
8395
0
                avm_rb_read_literal(rb, refresh_frame_flags_bits);
8396
0
          }
8397
0
        }
8398
0
      }
8399
0
    }
8400
1.94k
  }
8401
8402
18.3k
  if (cm->immediate_output_picture == 0 &&
8403
1
      current_frame->refresh_frame_flags == 0) {
8404
1
    avm_internal_error(
8405
1
        &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8406
1
        "If immediate_output_frame is equal to 0, it is a requirement "
8407
1
        "of bitstream conformance that refresh_frame_flags is not equal to 0.");
8408
1
  }
8409
8410
18.3k
  if (cm->is_leading_picture == 1) {
8411
    // other obu_types cannot overwrite the slots OBU_OPEN_LOOP_KEY is stored
8412
0
    for (int idx = 0; idx <= seq_params->max_mlayer_id; idx++) {
8413
0
      if (cm->olk_refresh_frame_flags[idx] == -1) continue;
8414
0
      if (current_frame->refresh_frame_flags &
8415
0
          cm->olk_refresh_frame_flags[idx]) {
8416
0
        avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
8417
0
                           "refresh_frame_flags(%d) of this frame(%s, doh=%d "
8418
0
                           "layerid=%d) overwrites "
8419
0
                           "one or more OLKs of mlyaer id, %d at %d in the "
8420
0
                           "reference list",
8421
0
                           current_frame->refresh_frame_flags,
8422
0
                           avm_obu_type_to_string(obu_type),
8423
0
                           cm->current_frame.display_order_hint, cm->mlayer_id,
8424
0
                           idx, cm->olk_refresh_frame_flags[idx]);
8425
0
      }
8426
0
    }
8427
0
  }
8428
8429
  // Record the refresh slots of regular VCL OBUs co-signalled with OLK in the
8430
  // same temporal unit so that reset_buffer_other_than_OLK() preserves them
8431
  // when the first regular temporal unit begins.
8432
18.3k
  if (pbi->olk_encountered && av2_is_regular_non_olk_obu(obu_type) &&
8433
0
      pbi->this_is_first_vcl_obu_in_tu == 0) {
8434
0
    memcpy(&cm->prev_olk_co_vcl_refresh_frame_flags[0],
8435
0
           &cm->olk_co_vcl_refresh_frame_flags[0],
8436
0
           MAX_NUM_MLAYERS * sizeof(cm->olk_co_vcl_refresh_frame_flags[0]));
8437
0
    if (cm->olk_co_vcl_refresh_frame_flags[cm->mlayer_id] == -1)
8438
0
      cm->olk_co_vcl_refresh_frame_flags[cm->mlayer_id] = 0;
8439
0
    cm->olk_co_vcl_refresh_frame_flags[cm->mlayer_id] |=
8440
0
        current_frame->refresh_frame_flags;
8441
0
  }
8442
8443
18.3k
  if (pbi->obu_type == OBU_RAS_FRAME || pbi->obu_type == OBU_OPEN_LOOP_KEY) {
8444
0
    check_long_term_ids_exist(pbi);
8445
0
  }
8446
8447
18.3k
  if (pbi->obu_type == OBU_RAS_FRAME) {
8448
0
    mark_reference_frames_with_long_term_ids(pbi);
8449
0
  }
8450
8451
18.3k
  features->allow_lf_sub_pu = 0;
8452
18.3k
  if (current_frame->frame_type == KEY_FRAME) {
8453
16.4k
    cm->current_frame.pyramid_level = 1;
8454
16.4k
    cm->current_frame.tlayer_id = cm->tlayer_id;
8455
16.4k
    cm->current_frame.mlayer_id = cm->mlayer_id;
8456
16.4k
    cm->current_frame.xlayer_id = cm->xlayer_id;
8457
16.4k
    features->tip_frame_mode = TIP_FRAME_DISABLED;
8458
16.4k
    setup_frame_size(cm, frame_size_override_flag, rb);
8459
16.4k
    read_screen_content_params(cm, rb);
8460
16.4k
    read_intrabc_params(cm, rb);
8461
16.4k
    features->allow_ref_frame_mvs = 0;
8462
16.4k
    cm->prev_frame = NULL;
8463
8464
16.4k
    cm->cur_frame->num_ref_frames = 0;
8465
16.4k
  } else {
8466
1.94k
    cm->current_frame.tlayer_id = cm->tlayer_id;
8467
1.94k
    cm->current_frame.mlayer_id = cm->mlayer_id;
8468
1.94k
    cm->current_frame.xlayer_id = cm->xlayer_id;
8469
8470
1.94k
    features->allow_ref_frame_mvs = 0;
8471
1.94k
    features->tip_frame_mode = TIP_FRAME_DISABLED;
8472
1.94k
    if (current_frame->frame_type == INTRA_ONLY_FRAME) {
8473
0
      setup_frame_size(cm, frame_size_override_flag, rb);
8474
0
      read_screen_content_params(cm, rb);
8475
0
      read_intrabc_params(cm, rb);
8476
8477
0
      cm->cur_frame->num_ref_frames = 0;
8478
8479
1.94k
    } else if (pbi->need_resync != 1) { /* Skip if need resync */
8480
0
      int use_olk_ref_only = pbi->olk_encountered &&
8481
0
                             av2_is_regular_non_olk_obu(obu_type) &&
8482
0
                             pbi->this_is_first_vcl_obu_in_tu == 0;
8483
      // Implicitly derive the reference mapping
8484
0
      init_ref_map_pair(cm, cm->ref_frame_map_pairs,
8485
0
                        current_frame->frame_type == KEY_FRAME,
8486
0
                        pbi->obu_type == OBU_RAS_FRAME, use_olk_ref_only);
8487
8488
0
      if (cm->bridge_frame_info.is_bridge_frame) {
8489
0
        current_frame->order_hint =
8490
0
            cm->ref_frame_map[cm->bridge_frame_info.bridge_frame_ref_idx]
8491
0
                ->order_hint;
8492
0
        current_frame->display_order_hint =
8493
0
            cm->ref_frame_map[cm->bridge_frame_info.bridge_frame_ref_idx]
8494
0
                ->display_order_hint;
8495
0
        current_frame->frame_number =
8496
0
            cm->ref_frame_map[cm->bridge_frame_info.bridge_frame_ref_idx]
8497
0
                ->order_hint;
8498
0
      }
8499
8500
      // For implicit reference mode, the reference mapping is derived without
8501
      // considering the resolution first. Later, setup_frame_size_with_refs
8502
      // uses the reference information to obtain the resolution.
8503
0
      av2_get_ref_frames(cm, current_frame->display_order_hint, 0, 0,
8504
0
                         cm->ref_frame_map_pairs);
8505
8506
      // Reference rankings will be implicitly derived in av2_get_ref_frames,
8507
      // but if the explicit mode is used, reference indices will be signaled,
8508
      // which overwrites the implictly derived ones.
8509
0
      int explicit_ref_frame_map = -1;
8510
      // explicit_ref_frame_map is always true when frame_type is s_frame.
8511
      // explicit_ref_frame_map is always false when frame_type is key_frame or
8512
      // intra_only frame. explicit_ref_frame_map is always false when
8513
      // seq_params->explicit_ref_frame_map is false and frame_type is not
8514
      // s_frame.
8515
0
      if (frame_is_sframe(cm))
8516
0
        explicit_ref_frame_map = 1;
8517
0
      else if (frame_is_intra_only(cm))
8518
0
        explicit_ref_frame_map = 0;
8519
0
      else if (cm->bridge_frame_info.is_bridge_frame)
8520
0
        explicit_ref_frame_map = 0;
8521
0
      else {
8522
0
        if (seq_params->enable_explicit_ref_frame_map)
8523
0
          explicit_ref_frame_map = avm_rb_read_bit(rb);
8524
0
        else
8525
0
          explicit_ref_frame_map = 0;
8526
0
      }
8527
8528
0
      if (explicit_ref_frame_map) {
8529
0
        cm->ref_frames_info.num_total_refs =
8530
0
            avm_rb_read_literal(rb, MAX_REFS_PER_FRAME_LOG2);
8531
0
        const int max_num_ref_frames =
8532
0
            AVMMIN(seq_params->ref_frames, INTER_REFS_PER_FRAME);
8533
        // Check whether num_total_refs read is valid
8534
0
        if (current_frame->frame_type != S_FRAME)
8535
0
          if (cm->ref_frames_info.num_total_refs < 0 ||
8536
0
              cm->ref_frames_info.num_total_refs > max_num_ref_frames)
8537
0
            avm_internal_error(&cm->error, AVM_CODEC_ERROR,
8538
0
                               "Invalid num_total_refs");
8539
0
        for (int i = 0; i < cm->ref_frames_info.num_total_refs; ++i) {
8540
0
          int ref = avm_rb_read_literal(rb, seq_params->ref_frames_log2);
8541
0
          if (ref >= seq_params->ref_frames) {
8542
0
            avm_internal_error(
8543
0
                &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8544
0
                "Explicit ref frame idx must be less than %d but is set to %d",
8545
0
                seq_params->ref_frames, ref);
8546
0
          }
8547
8548
          // Most of the time, streams start with a keyframe. In that case,
8549
          // ref_frame_map will have been filled in at that point and will not
8550
          // contain any NULLs. However, streams are explicitly allowed to start
8551
          // with an intra-only frame, so long as they don't then signal a
8552
          // reference to a slot that hasn't been set yet. That's what we are
8553
          // checking here.
8554
0
          if (cm->ref_frame_map[ref] == NULL)
8555
0
            avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
8556
0
                               "Inter frame requests nonexistent reference");
8557
          // mlayer and tlayer scalability related bitstream constraints for the
8558
          // explicit reference frame signaling
8559
0
          const int cur_mlayer_id = current_frame->mlayer_id;
8560
0
          const int ref_mlayer_id = cm->ref_frame_map[ref]->mlayer_id;
8561
0
          if (!is_mlayer_scalable_and_dependent(seq_params, cur_mlayer_id,
8562
0
                                                ref_mlayer_id)) {
8563
0
            avm_internal_error(
8564
0
                &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8565
0
                "Unsupported bitstream: embedded layer scalability shall be "
8566
0
                "maintained in explicit reference map signaling.");
8567
0
          }
8568
0
          const int cur_tlayer_id = current_frame->tlayer_id;
8569
0
          const int ref_tlayer_id = cm->ref_frame_map[ref]->tlayer_id;
8570
0
          if (!is_tlayer_scalable_and_dependent(seq_params, cur_tlayer_id,
8571
0
                                                ref_tlayer_id, cur_mlayer_id)) {
8572
0
            avm_internal_error(
8573
0
                &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8574
0
                "Unsupported bitstream: temporal layer scalability shall be "
8575
0
                "maintained in explicit reference map signaling.");
8576
0
          }
8577
0
          cm->remapped_ref_idx[i] = ref;
8578
0
        }
8579
0
      }
8580
0
      if (!frame_is_sframe(cm) && frame_size_override_flag &&
8581
0
          !cm->bridge_frame_info.is_bridge_frame) {
8582
0
        setup_frame_size_with_refs(cm, explicit_ref_frame_map, rb);
8583
0
      } else {
8584
0
        setup_frame_size(cm, frame_size_override_flag, rb);
8585
0
      }
8586
8587
      // Overwrite the reference mapping considering the resolution
8588
0
      if (!explicit_ref_frame_map) {
8589
0
        av2_get_ref_frames(cm, current_frame->display_order_hint, 1, 0,
8590
0
                           cm->ref_frame_map_pairs);
8591
8592
        // Note: The following if block implements bitstream constraint checks
8593
        // for consistent reference frame mapping when (embedded or temporal)
8594
        // layers are selectively dropped based on operating points. The
8595
        // following code provides checks for possible operating point
8596
        // combinations and decoders may choose to simplify this check depending
8597
        // on the desired operating point(s) specified in the operating point
8598
        // set (OPS).
8599
0
        if (pbi->dec_op_params.isValid &&
8600
0
            is_layer_within_op_profiles(pbi, cm->tlayer_id, cm->mlayer_id)) {
8601
0
          int ref_index_list[INTER_REFS_PER_FRAME];
8602
0
          int constrained_ref_index_list[INTER_REFS_PER_FRAME];
8603
          // number of layer-drop masks
8604
0
          const int num_mlayer_masks = 1 << (cm->mlayer_id + 1);
8605
0
          const int num_tlayer_masks = 1 << (cm->tlayer_id + 1);
8606
          // derive operating point masks for mlayer and tlayer
8607
0
          int op_mlayer_mask, op_tlayer_mask;
8608
0
          create_op_masks_from_profiles(pbi, &op_tlayer_mask, &op_mlayer_mask);
8609
          // Check consistency for subsets of OPs that would include the current
8610
          // frame. Skip subsets where the current frame's layer would be
8611
          // dropped.
8612
0
          for (int ml = 0; ml < num_mlayer_masks; ml++) {
8613
0
            for (int tl = 0; tl < num_tlayer_masks; tl++) {
8614
0
              int mlayer_mask = ml & op_mlayer_mask;
8615
0
              int tlayer_mask = tl & op_tlayer_mask;
8616
              // Skip subsets that would drop the current frame's layer.
8617
0
              if (is_layer_dropped(cm->mlayer_id, mlayer_mask) ||
8618
0
                  is_layer_dropped(cm->tlayer_id, tlayer_mask))
8619
0
                continue;
8620
              // Skip subsets with unsatisfied layer dependencies.
8621
0
              if (check_missing_layer_dependency(cm, mlayer_mask, tlayer_mask))
8622
0
                continue;
8623
              // derive OP constrained mapping and store in
8624
              // cm->op_remapped_ref_idx[]
8625
0
              const int default_map_idx = av2_get_op_constrained_ref_frames(
8626
0
                  cm, current_frame->display_order_hint, 0,
8627
0
                  cm->ref_frame_map_pairs, mlayer_mask, tlayer_mask);
8628
0
              for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
8629
                // get constrained mapped reference list
8630
0
                constrained_ref_index_list[i] = cm->op_remapped_ref_idx[i];
8631
                // set ref_index_list for lower operating points
8632
0
                const int map_idx = cm->remapped_ref_idx[i];
8633
0
                ref_index_list[i] = map_idx;
8634
0
                const RefFrameMapPair ref_info =
8635
0
                    cm->ref_frame_map_pairs[map_idx];
8636
0
                if (is_layer_dropped(ref_info.mlayer_id, mlayer_mask) ||
8637
0
                    is_layer_dropped(ref_info.tlayer_id, tlayer_mask)) {
8638
0
                  ref_index_list[i] = default_map_idx;
8639
0
                }
8640
0
              }
8641
              // check if reference mapping is consistent accross possible
8642
              // operating points
8643
0
              if (!is_reference_mapping_consistent(
8644
0
                      ref_index_list, constrained_ref_index_list)) {
8645
0
                avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8646
0
                                   "Inconsistent reference index mapping "
8647
0
                                   "accross different operating points.");
8648
0
              }
8649
0
            }
8650
0
          }
8651
0
        }
8652
0
      }
8653
      // Check to make sure all reference frames have valid dimensions.
8654
0
      for (int i = 0; i < cm->ref_frames_info.num_total_refs; ++i) {
8655
0
        const RefCntBuffer *const ref_frame = get_ref_frame_buf(cm, i);
8656
0
        int valid_ref_frame = valid_ref_frame_size(ref_frame->buf.y_crop_width,
8657
0
                                                   ref_frame->buf.y_crop_height,
8658
0
                                                   cm->width, cm->height);
8659
0
        if (!valid_ref_frame && !ref_frame->is_restricted)
8660
0
          avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
8661
0
                             "Referenced frame has invalid size");
8662
0
      }
8663
0
      if (obu_type != OBU_LEADING_TIP && obu_type != OBU_REGULAR_TIP &&
8664
0
          current_frame->frame_type == INTER_FRAME) {
8665
0
        setup_bru_active_info(cm, rb);
8666
0
        if (cm->bru.enabled) {
8667
0
          const RefCntBuffer *const bru_ref =
8668
0
              get_ref_frame_buf(cm, cm->bru.update_ref_idx);
8669
0
          if (bru_ref != NULL && bru_ref->is_restricted) {
8670
0
            avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
8671
0
                               "Invalid BRU Ref: restricted reference buffer");
8672
0
          }
8673
0
          if (bru_ref == NULL) {
8674
0
            avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
8675
0
                               "Invalid BRU Ref: invalid reference buffer");
8676
0
          } else {
8677
0
            if (bru_ref->width != cm->width || bru_ref->height != cm->height) {
8678
0
              avm_internal_error(
8679
0
                  &cm->error, AVM_CODEC_CORRUPT_FRAME,
8680
0
                  "BRU reference frame size is not the same as current frame");
8681
0
            }
8682
0
          }
8683
0
        }
8684
0
      }
8685
0
      if (cm->bru.frame_inactive_flag ||
8686
0
          cm->bridge_frame_info.is_bridge_frame) {
8687
0
        cm->features.disable_cdf_update = 1;
8688
0
      }
8689
0
      cm->ref_frames_info.num_same_ref_compound =
8690
0
          AVMMIN(cm->seq_params.num_same_ref_compound,
8691
0
                 cm->ref_frames_info.num_total_refs);
8692
0
      if (features->primary_ref_frame >= cm->ref_frames_info.num_total_refs &&
8693
0
          features->primary_ref_frame != PRIMARY_REF_NONE) {
8694
0
        avm_internal_error(&cm->error, AVM_CODEC_ERROR,
8695
0
                           "Invalid primary_ref_frame");
8696
0
      }
8697
0
      for (int i = 0; i < cm->ref_frames_info.num_total_refs; ++i) {
8698
0
        int ref = 0;
8699
0
        if (!explicit_ref_frame_map) {
8700
0
          if (cm->bridge_frame_info.is_bridge_frame) {
8701
0
            const int ref_frame =
8702
0
                cm->bridge_frame_info.bridge_frame_ref_idx_remapped;
8703
0
            assert(!is_tip_ref_frame(
8704
0
                ref_frame));  // TIP frame reference is not allowed
8705
0
            ref = get_ref_frame_map_idx(cm, ref_frame);
8706
0
          } else {
8707
0
            ref = cm->remapped_ref_idx[i];
8708
0
            if (cm->ref_frame_map[ref] == NULL)
8709
0
              avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
8710
0
                                 "Inter frame requests nonexistent reference");
8711
0
          }
8712
0
        } else {
8713
0
          ref = cm->remapped_ref_idx[i];
8714
0
        }
8715
        // find corresponding bru ref idx given explicit_bru_idx
8716
0
        if (cm->bru.enabled && cm->bru.update_ref_idx == i) {
8717
0
          cm->bru.ref_disp_order = cm->ref_frame_map[ref]->display_order_hint;
8718
0
          cm->bru.explicit_ref_idx = ref;
8719
0
        }
8720
        // Check valid for referencing
8721
0
        if (pbi->valid_for_referencing[ref] == 0)
8722
0
          avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
8723
0
                             "Reference frame not valid for referencing");
8724
        // Check that co-VCL frames in an OLK TU only reference frames written
8725
        // in the current TU.
8726
0
        if (pbi->olk_encountered && !pbi->this_is_first_vcl_obu_in_tu &&
8727
0
            av2_is_regular_non_olk_obu(obu_type)) {
8728
0
          const RefCntBuffer *const ref_buf = cm->ref_frame_map[ref];
8729
0
          const int ref_mlayer_id = ref_buf->mlayer_id;
8730
0
          const int ref_tlayer_id = ref_buf->tlayer_id;
8731
0
          const int cur_mlayer_id = current_frame->mlayer_id;
8732
0
          const int cur_tlayer_id = current_frame->tlayer_id;
8733
          // Only check references from layers the current frame depends on.
8734
0
          if (is_mlayer_scalable_and_dependent(&cm->seq_params, cur_mlayer_id,
8735
0
                                               ref_mlayer_id) &&
8736
0
              is_tlayer_scalable_and_dependent(&cm->seq_params, cur_tlayer_id,
8737
0
                                               ref_tlayer_id, cur_mlayer_id)) {
8738
            // Build a bitmask of DPB slots written in the current TU from all
8739
            // mlayers that the current frame depends on.
8740
0
            int current_tu_ref_flags = 0;
8741
0
            for (int layer = 0; layer <= cm->seq_params.max_mlayer_id;
8742
0
                 layer++) {
8743
0
              if (!is_mlayer_scalable_and_dependent(&cm->seq_params,
8744
0
                                                    cur_mlayer_id, layer))
8745
0
                continue;
8746
0
              if (cm->olk_refresh_frame_flags[layer] != -1)
8747
0
                current_tu_ref_flags |= cm->olk_refresh_frame_flags[layer];
8748
0
              if (cm->prev_olk_co_vcl_refresh_frame_flags[layer] != -1)
8749
0
                current_tu_ref_flags |=
8750
0
                    cm->prev_olk_co_vcl_refresh_frame_flags[layer];
8751
0
            }
8752
0
            if (!((current_tu_ref_flags >> ref) & 1)) {
8753
0
              avm_internal_error(
8754
0
                  &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8755
0
                  "Co-VCL frame (doh=%d, mlayer=%d) in OLK TU references DPB "
8756
0
                  "slot %d (mlayer=%d, tlayer=%d) which was not written in the "
8757
0
                  "current temporal unit",
8758
0
                  current_frame->display_order_hint, cur_mlayer_id, ref,
8759
0
                  ref_mlayer_id, ref_tlayer_id);
8760
0
            }
8761
0
          }
8762
0
        }
8763
0
      }
8764
0
      if (cm->bru.update_ref_idx != -1) {
8765
0
        for (int i = 0; i < cm->ref_frames_info.num_total_refs; ++i) {
8766
0
          if (cm->bru.update_ref_idx != i) {
8767
0
            if (cm->ref_frame_map[cm->bru.explicit_ref_idx] ==
8768
0
                cm->ref_frame_map[cm->remapped_ref_idx[i]]) {
8769
0
              avm_internal_error(&cm->error, AVM_CODEC_ERROR,
8770
0
                                 "Only one reference can be updated for BRU");
8771
0
            }
8772
0
          }
8773
0
        }
8774
        // The BRU reference buffer slot must be refreshed by this frame;
8775
0
        if (!(current_frame->refresh_frame_flags &
8776
0
              (1 << cm->bru.explicit_ref_idx))) {
8777
0
          avm_internal_error(&cm->error, AVM_CODEC_ERROR,
8778
0
                             "BRU ref (explicit_ref_idx=%d) must be included "
8779
0
                             "in refresh_frame_flags (0x%x)",
8780
0
                             cm->bru.explicit_ref_idx,
8781
0
                             current_frame->refresh_frame_flags);
8782
0
        }
8783
0
      }
8784
0
      if (cm->bru.enabled) {
8785
0
        int n_future = 0;
8786
0
        int cur_frame_disp = (int)current_frame->display_order_hint;
8787
0
        for (int i = 0; i < cm->seq_params.ref_frames; i++) {
8788
0
          const RefCntBuffer *const buf = cm->ref_frame_map[i];
8789
0
          if (buf) {
8790
0
            if (buf->is_restricted) continue;
8791
0
            int ref_disp = (int)buf->display_order_hint;
8792
0
            const int disp_diff = get_relative_dist(
8793
0
                &cm->seq_params.order_hint_info, cur_frame_disp, ref_disp);
8794
0
            if (disp_diff < 0) {
8795
0
              n_future++;
8796
0
              break;
8797
0
            }
8798
0
          }
8799
0
        }
8800
0
        if (n_future > 0) {
8801
0
          avm_internal_error(&cm->error, AVM_CODEC_ERROR,
8802
0
                             "BRU can only use in LD");
8803
0
        }
8804
0
      }
8805
      // With explicit_ref_frame_map, cm->remapped_ref_idx has been
8806
      // overwritten. The reference lists also needs to be reset.
8807
0
      if (explicit_ref_frame_map) {
8808
0
        RefScoreData scores[REF_FRAMES];
8809
0
        for (int i = 0; i < seq_params->ref_frames; i++)
8810
0
          scores[i].score = INT_MAX;
8811
0
        for (int i = 0; i < cm->ref_frames_info.num_total_refs; i++) {
8812
0
          if (cm->ref_frame_map[cm->remapped_ref_idx[i]]->is_restricted) {
8813
0
            scores[i].distance = (1 << (RELATIVE_DIST_BITS - 1)) - 1;
8814
0
          } else {
8815
0
            scores[i].score = i;
8816
0
            int ref = cm->remapped_ref_idx[i];
8817
0
            scores[i].distance =
8818
0
                get_relative_dist(&seq_params->order_hint_info,
8819
0
                                  (int)current_frame->display_order_hint,
8820
0
                                  (int)cm->ref_frame_map_pairs[ref].disp_order);
8821
0
          }
8822
0
          cm->ref_frames_info.ref_frame_distance[i] = scores[i].distance;
8823
0
        }
8824
0
        update_num_restricted_ref(cm);
8825
0
        av2_get_past_future_cur_ref_lists(cm, scores);
8826
0
      }
8827
0
      cm->cur_frame->num_ref_frames = cm->ref_frames_info.num_total_refs;
8828
8829
0
      if (frame_might_allow_ref_frame_mvs(cm))
8830
0
        features->allow_ref_frame_mvs = avm_rb_read_bit(rb);
8831
0
      else
8832
0
        features->allow_ref_frame_mvs = 0;
8833
0
      if (features->allow_ref_frame_mvs &&
8834
0
          cm->ref_frames_info.num_total_refs > 1 &&
8835
0
          block_size_high[seq_params->sb_size] > 64) {
8836
        // Get the TMVP sampling mode
8837
0
        cm->tmvp_sample_step = avm_rb_read_bit(rb) + 1;
8838
0
        cm->tmvp_sample_stepl2 = cm->tmvp_sample_step == 1 ? 0 : 1;
8839
0
      } else {
8840
0
        cm->tmvp_sample_step = 1;
8841
0
        cm->tmvp_sample_stepl2 = 0;
8842
0
      }
8843
8844
0
      cm->tip_global_motion.as_int = 0;
8845
0
      cm->tip_interp_filter = MULTITAP_SHARP;
8846
0
      cm->tip_global_wtd_index = 0;
8847
0
      cm->has_both_sides_refs = (cm->ref_frames_info.num_future_refs > 0) &&
8848
0
                                (cm->ref_frames_info.num_past_refs > 0);
8849
0
      if (cm->seq_params.enable_tip && features->allow_ref_frame_mvs &&
8850
0
          cm->ref_frames_info.num_total_refs >= 2 &&
8851
0
          !cm->bridge_frame_info.is_bridge_frame &&
8852
0
          !cm->bru.frame_inactive_flag) {
8853
0
        if (obu_type == OBU_REGULAR_TIP || obu_type == OBU_LEADING_TIP) {
8854
0
          features->tip_frame_mode = TIP_FRAME_AS_OUTPUT;
8855
0
        } else {
8856
0
          features->tip_frame_mode =
8857
0
              avm_rb_read_bit(rb) ? TIP_FRAME_AS_REF : TIP_FRAME_DISABLED;
8858
0
        }
8859
8860
0
        read_frame_opfl_refine_type(cm, rb);
8861
8862
0
        if (features->tip_frame_mode && cm->seq_params.enable_tip_hole_fill) {
8863
0
          features->allow_tip_hole_fill = avm_rb_read_bit(rb);
8864
0
        } else {
8865
0
          features->allow_tip_hole_fill = false;
8866
0
        }
8867
8868
0
        if (features->tip_frame_mode && is_unequal_weighted_tip_allowed(cm)) {
8869
0
          cm->tip_global_wtd_index = avm_rb_read_literal(rb, 3);
8870
0
        }
8871
8872
0
        if (features->tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
8873
0
          int all_zero = avm_rb_read_bit(rb);
8874
0
          if (!all_zero) {
8875
0
            cm->tip_global_motion.as_mv.row = avm_rb_read_literal(rb, 4);
8876
0
            cm->tip_global_motion.as_mv.col = avm_rb_read_literal(rb, 4);
8877
0
            if (cm->tip_global_motion.as_mv.row != 0) {
8878
0
              int sign = avm_rb_read_bit(rb);
8879
0
              if (sign) cm->tip_global_motion.as_mv.row *= -1;
8880
0
            }
8881
0
            if (cm->tip_global_motion.as_mv.col != 0) {
8882
0
              int sign = avm_rb_read_bit(rb);
8883
0
              if (sign) cm->tip_global_motion.as_mv.col *= -1;
8884
0
            }
8885
0
          }
8886
8887
0
          if (avm_rb_read_bit(rb)) {
8888
0
            cm->tip_interp_filter = MULTITAP_SHARP;
8889
0
          } else if (avm_rb_read_bit(rb)) {
8890
0
            cm->tip_interp_filter = EIGHTTAP_REGULAR;
8891
0
          } else {
8892
0
            cm->tip_interp_filter = EIGHTTAP_SMOOTH;
8893
0
          }
8894
0
        }
8895
0
      } else {
8896
0
        features->tip_frame_mode = TIP_FRAME_DISABLED;
8897
0
        if (!cm->bru.frame_inactive_flag &&
8898
0
            !cm->bridge_frame_info.is_bridge_frame)
8899
0
          read_frame_opfl_refine_type(cm, rb);
8900
0
      }
8901
8902
0
      if (features->tip_frame_mode != TIP_FRAME_AS_OUTPUT &&
8903
0
          !cm->bridge_frame_info.is_bridge_frame &&
8904
0
          !cm->bru.frame_inactive_flag) {
8905
0
        read_screen_content_params(cm, rb);
8906
0
        read_intrabc_params(cm, rb);
8907
0
        read_frame_max_drl_bits(cm, rb);
8908
0
        if (features->cur_frame_force_integer_mv) {
8909
0
          features->fr_mv_precision = MV_PRECISION_ONE_PEL;
8910
0
        } else {
8911
0
          if (avm_rb_read_bit(rb)) {
8912
0
            features->fr_mv_precision = MV_PRECISION_QTR_PEL;
8913
0
          } else {
8914
0
            features->fr_mv_precision = avm_rb_read_bit(rb)
8915
0
                                            ? MV_PRECISION_ONE_EIGHTH_PEL
8916
0
                                            : MV_PRECISION_HALF_PEL;
8917
0
          }
8918
8919
0
          features->most_probable_fr_mv_precision = features->fr_mv_precision;
8920
0
        }
8921
0
        if (features->fr_mv_precision == MV_PRECISION_ONE_PEL) {
8922
0
          features->use_pb_mv_precision = 0;
8923
0
        } else {
8924
0
          features->use_pb_mv_precision = cm->seq_params.enable_flex_mvres;
8925
0
        }
8926
8927
0
        features->interp_filter = read_frame_interp_filter(rb);
8928
0
        int seq_enabled_motion_modes = cm->seq_params.seq_enabled_motion_modes;
8929
8930
0
        if (cm->seq_params.seq_frame_motion_modes_present_flag) {
8931
0
          int frame_enabled_motion_modes = (1 << SIMPLE_TRANSLATION);
8932
0
          for (int motion_mode = INTERINTRA; motion_mode < MOTION_MODES;
8933
0
               motion_mode++) {
8934
0
            if (seq_enabled_motion_modes & (1 << motion_mode)) {
8935
0
              int enabled = avm_rb_read_bit(rb);
8936
0
              if (enabled) {
8937
0
                frame_enabled_motion_modes |= (1 << motion_mode);
8938
0
              }
8939
0
            }
8940
0
          }
8941
0
          features->enabled_motion_modes = frame_enabled_motion_modes;
8942
0
        } else {
8943
0
          features->enabled_motion_modes =
8944
0
              cm->seq_params.seq_enabled_motion_modes;
8945
0
        }
8946
0
      }
8947
0
    }
8948
8949
1.94k
    if (!(current_frame->frame_type == INTRA_ONLY_FRAME) &&
8950
0
        pbi->need_resync != 1) {
8951
0
      for (int i = 0; i < cm->ref_frames_info.num_total_refs; ++i) {
8952
0
        const RefCntBuffer *const ref_buf = get_ref_frame_buf(cm, i);
8953
0
        if (!ref_buf) continue;
8954
0
        struct scale_factors *const ref_scale_factors =
8955
0
            get_ref_scale_factors(cm, i);
8956
0
        av2_setup_scale_factors_for_frame(
8957
0
            ref_scale_factors, ref_buf->buf.y_crop_width,
8958
0
            ref_buf->buf.y_crop_height, cm->width, cm->height);
8959
0
        if ((!av2_is_valid_scale(ref_scale_factors)))
8960
0
          avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8961
0
                             "Reference frame has invalid dimensions");
8962
0
      }
8963
8964
0
      if (cm->seq_params.enable_tip) {
8965
0
        const RefCntBuffer *const ref_buf = get_ref_frame_buf(cm, TIP_FRAME);
8966
0
        if (ref_buf) {
8967
0
          struct scale_factors *const ref_scale_factors =
8968
0
              get_ref_scale_factors(cm, TIP_FRAME);
8969
0
          av2_setup_scale_factors_for_frame(
8970
0
              ref_scale_factors, ref_buf->buf.y_crop_width,
8971
0
              ref_buf->buf.y_crop_height, cm->width, cm->height);
8972
0
          if ((!av2_is_valid_scale(ref_scale_factors)))
8973
0
            avm_internal_error(&cm->error, AVM_CODEC_UNSUP_BITSTREAM,
8974
0
                               "Reference frame has invalid dimensions");
8975
0
        }
8976
0
      }
8977
0
    }
8978
1.94k
  }
8979
8980
18.3k
  av2_setup_frame_buf_refs(cm);
8981
8982
18.3k
  cm->cur_frame->frame_type = current_frame->frame_type;
8983
18.3k
  cm->cur_frame->is_restricted_switch_frame =
8984
18.3k
      (current_frame->frame_type == S_FRAME &&
8985
0
       cm->restricted_prediction_switch);
8986
18.3k
  cm->cur_frame->mlayer_id = cm->mlayer_id;
8987
18.3k
  cm->cur_frame->xlayer_id = cm->xlayer_id;
8988
18.3k
  cm->cur_frame->stream_id = av2_get_stream_index(cm, cm->xlayer_id);
8989
18.3k
  validate_references(pbi);
8990
8991
18.3k
  cm->cur_frame->buf.bit_depth = seq_params->bit_depth;
8992
18.3k
  cm->cur_frame->buf.color_primaries = color_info->color_primaries;
8993
18.3k
  cm->cur_frame->buf.transfer_characteristics =
8994
18.3k
      color_info->transfer_characteristics;
8995
18.3k
  cm->cur_frame->buf.matrix_coefficients = color_info->matrix_coefficients;
8996
18.3k
  cm->cur_frame->buf.monochrome = seq_params->monochrome;
8997
18.3k
  if (ci_params->ci_chroma_sample_position_present_flag)
8998
0
    cm->cur_frame->buf.chroma_sample_position =
8999
0
        ci_params->ci_chroma_sample_position[0];
9000
18.3k
  else
9001
18.3k
    cm->cur_frame->buf.chroma_sample_position = AVM_CSP_UNSPECIFIED;
9002
18.3k
  cm->cur_frame->buf.color_range = color_info->full_range_flag;
9003
18.3k
  cm->cur_frame->buf.render_width = cm->render_width;
9004
18.3k
  cm->cur_frame->buf.render_height = cm->render_height;
9005
9006
18.3k
  YV12_BUFFER_CONFIG *tip_frame_buf = &cm->tip_ref.tmp_tip_frame->buf;
9007
18.3k
  tip_frame_buf->bit_depth = seq_params->bit_depth;
9008
18.3k
  tip_frame_buf->color_primaries = color_info->color_primaries;
9009
18.3k
  tip_frame_buf->transfer_characteristics =
9010
18.3k
      color_info->transfer_characteristics;
9011
18.3k
  tip_frame_buf->matrix_coefficients = color_info->matrix_coefficients;
9012
18.3k
  tip_frame_buf->monochrome = seq_params->monochrome;
9013
18.3k
  if (ci_params->ci_chroma_sample_position_present_flag)
9014
0
    tip_frame_buf->chroma_sample_position =
9015
0
        ci_params->ci_chroma_sample_position[0];
9016
18.3k
  else
9017
18.3k
    tip_frame_buf->chroma_sample_position = AVM_CSP_UNSPECIFIED;
9018
18.3k
  tip_frame_buf->color_range = color_info->full_range_flag;
9019
18.3k
  tip_frame_buf->render_width = cm->render_width;
9020
18.3k
  tip_frame_buf->render_height = cm->render_height;
9021
9022
18.3k
  if (pbi->need_resync) {
9023
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9024
0
                       "Keyframe / intra-only frame required to reset decoder"
9025
0
                       " state");
9026
0
  }
9027
18.3k
  xd->bd = (int)seq_params->bit_depth;
9028
18.3k
  if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) {
9029
    // Set parameters corresponding to no filtering.
9030
0
    struct loopfilter *lf = &cm->lf;
9031
0
    lf->apply_deblocking_filter[0] = 0;
9032
0
    lf->apply_deblocking_filter[1] = 0;
9033
0
    cm->cdef_info.cdef_frame_enable = 0;
9034
0
    cm->gdf_info.gdf_mode = 0;
9035
    // set cm->rst_info and copy it to cur_frame->rst_info
9036
0
    for (int plane = 0; plane < av2_num_planes(cm); plane++) {
9037
0
      cm->rst_info[plane].frame_restoration_type = RESTORE_NONE;
9038
0
      cm->rst_info[plane].frame_filters_on = 0;
9039
0
      av2_copy_rst_frame_filters(&cm->cur_frame->rst_info[plane],
9040
0
                                 &cm->rst_info[plane]);
9041
0
      cm->cur_frame->rst_info[plane].num_filter_classes = 0;
9042
0
      cm->cur_frame->rst_info[plane].rst_ref_pic_idx = 0;
9043
0
      cm->cur_frame->rst_info[plane].temporal_pred_flag = 0;
9044
0
    }
9045
0
    features->disable_cdf_update = 1;
9046
0
    const RefCntBuffer *ref_buf;
9047
0
    if (cm->bridge_frame_info.is_bridge_frame) {
9048
0
      ref_buf = get_ref_frame_buf(
9049
0
          cm, cm->bridge_frame_info.bridge_frame_ref_idx_remapped);
9050
0
    } else {
9051
0
      ref_buf = get_ref_frame_buf(cm, cm->bru.update_ref_idx);
9052
0
    }
9053
    // set cm->ccso_info and copy to cur_frame->ccso_info
9054
    // doing once in uncompred header
9055
0
    cm->ccso_info.ccso_frame_flag = 0;
9056
0
    for (int plane = 0; plane < CCSO_NUM_COMPONENTS; plane++) {
9057
0
      if (cm->bru.frame_inactive_flag ||
9058
0
          cm->bridge_frame_info.is_bridge_frame) {
9059
0
        cm->ccso_info.reuse_ccso[plane] = 0;
9060
0
        cm->ccso_info.sb_reuse_ccso[plane] = 0;
9061
0
        cm->ccso_info.ccso_ref_idx[plane] = UINT8_MAX;
9062
0
        cm->ccso_info.ccso_enable[plane] = 0;
9063
0
        av2_copy_ccso_filters(&cm->cur_frame->ccso_info, &cm->ccso_info, plane,
9064
0
                              1, 0, 0);
9065
0
        continue;
9066
0
      }
9067
0
    }
9068
0
    cm->quant_params.base_qindex = ref_buf->base_qindex;
9069
0
    if (av2_num_planes(cm) > 1) {
9070
0
      cm->quant_params.u_ac_delta_q = ref_buf->u_ac_delta_q;
9071
0
      cm->quant_params.v_ac_delta_q = ref_buf->v_ac_delta_q;
9072
0
    } else {
9073
0
      cm->quant_params.v_ac_delta_q = cm->quant_params.u_ac_delta_q = 0;
9074
0
    }
9075
0
    cm->cur_frame->base_qindex = cm->quant_params.base_qindex;
9076
0
    cm->cur_frame->u_ac_delta_q = cm->quant_params.u_ac_delta_q;
9077
0
    cm->cur_frame->v_ac_delta_q = cm->quant_params.v_ac_delta_q;
9078
9079
    // Bridge frames should inherit the restricted status from their reference
9080
0
    cm->cur_frame->is_restricted = ref_buf->is_restricted;
9081
9082
0
    set_primary_ref_frame_and_ctx(pbi);
9083
9084
0
    CommonContexts *const above_contexts = &cm->above_contexts;
9085
0
    if (above_contexts->num_planes < av2_num_planes(cm) ||
9086
0
        above_contexts->num_mi_cols < cm->mi_params.mi_cols ||
9087
0
        above_contexts->num_tile_rows < cm->tiles.rows) {
9088
0
      av2_free_above_context_buffers(above_contexts);
9089
0
      if (av2_alloc_above_context_buffers(above_contexts, cm->tiles.rows,
9090
0
                                          cm->mi_params.mi_cols,
9091
0
                                          av2_num_planes(cm))) {
9092
0
        avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
9093
0
                           "Failed to allocate context buffers");
9094
0
      }
9095
0
    }
9096
9097
0
    setup_film_grain(pbi, rb);
9098
0
    return 0;
9099
0
  }
9100
9101
18.3k
  if (features->tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
9102
    // Set parameters corresponding to no filtering.
9103
0
    struct loopfilter *lf = &cm->lf;
9104
0
    lf->apply_deblocking_filter[0] = 0;
9105
0
    lf->apply_deblocking_filter[1] = 0;
9106
9107
0
    cm->gdf_info.gdf_mode = 0;
9108
9109
0
    cm->cdef_info.cdef_frame_enable = 0;
9110
0
    cm->rst_info[0].frame_restoration_type = RESTORE_NONE;
9111
0
    cm->rst_info[1].frame_restoration_type = RESTORE_NONE;
9112
0
    cm->rst_info[2].frame_restoration_type = RESTORE_NONE;
9113
0
  }
9114
9115
18.3k
  if (features->tip_frame_mode != TIP_FRAME_AS_OUTPUT) {
9116
16.3k
    if (!cm->bridge_frame_info.is_bridge_frame) {
9117
16.3k
      features->disable_cdf_update = avm_rb_read_bit(rb);
9118
16.3k
    } else {
9119
0
      features->disable_cdf_update = 1;
9120
0
    }
9121
9122
16.3k
    read_tile_info(pbi, rb);
9123
16.3k
    if (!av2_is_min_tile_width_satisfied(cm)) {
9124
0
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9125
0
                         "Minimum tile width requirement not satisfied");
9126
0
    }
9127
9128
16.3k
    CommonQuantParams *const quant_params = &cm->quant_params;
9129
16.3k
    setup_quantization(quant_params, av2_num_planes(cm), &cm->seq_params, rb);
9130
16.3k
    cm->cur_frame->base_qindex = quant_params->base_qindex;
9131
16.3k
    cm->cur_frame->u_ac_delta_q = quant_params->u_ac_delta_q;
9132
16.3k
    cm->cur_frame->v_ac_delta_q = quant_params->v_ac_delta_q;
9133
9134
16.3k
    set_primary_ref_frame_and_ctx(pbi);
9135
9136
16.3k
    CommonContexts *const above_contexts = &cm->above_contexts;
9137
16.3k
    if (above_contexts->num_planes < av2_num_planes(cm) ||
9138
14.3k
        above_contexts->num_mi_cols < cm->mi_params.mi_cols ||
9139
14.2k
        above_contexts->num_tile_rows < cm->tiles.rows) {
9140
2.09k
      av2_free_above_context_buffers(above_contexts);
9141
2.09k
      if (av2_alloc_above_context_buffers(above_contexts, cm->tiles.rows,
9142
2.09k
                                          cm->mi_params.mi_cols,
9143
2.09k
                                          av2_num_planes(cm))) {
9144
0
        avm_internal_error(&cm->error, AVM_CODEC_MEM_ERROR,
9145
0
                           "Failed to allocate context buffers");
9146
0
      }
9147
2.09k
    }
9148
9149
16.3k
    setup_segmentation(cm, rb);
9150
9151
16.3k
    setup_qm_params(pbi, quant_params, cm->seg.enabled, av2_num_planes(cm), rb);
9152
16.3k
    cm->delta_q_info.delta_q_res = 1;
9153
16.3k
    cm->delta_q_info.delta_q_present_flag =
9154
16.3k
        quant_params->base_qindex > 0 ? avm_rb_read_bit(rb) : 0;
9155
16.3k
    if (cm->delta_q_info.delta_q_present_flag) {
9156
10.9k
      xd->current_base_qindex = quant_params->base_qindex;
9157
10.9k
      cm->delta_q_info.delta_q_res = 1 << avm_rb_read_literal(rb, 2);
9158
10.9k
    }
9159
9160
16.3k
    xd->cur_frame_force_integer_mv = features->cur_frame_force_integer_mv;
9161
16.3k
    features->has_lossless_segment = 0;
9162
9163
16.3k
    const int max_seg_num =
9164
16.3k
        cm->seg.enable_ext_seg ? MAX_SEGMENTS : MAX_SEGMENTS_8;
9165
148k
    for (int i = 0; i < max_seg_num; i++) {
9166
132k
      const int qindex = av2_get_qindex(&cm->seg, i, quant_params->base_qindex,
9167
132k
                                        cm->seq_params.bit_depth);
9168
132k
      xd->lossless[i] =
9169
132k
          qindex == 0 && cm->delta_q_info.delta_q_present_flag == 0 &&
9170
11.8k
          (quant_params->y_dc_delta_q + cm->seq_params.base_y_dc_delta_q <=
9171
11.8k
           0) &&
9172
11.3k
          (quant_params->u_dc_delta_q + cm->seq_params.base_uv_dc_delta_q <=
9173
11.3k
           0) &&
9174
6.54k
          (quant_params->v_dc_delta_q + cm->seq_params.base_uv_dc_delta_q <=
9175
6.54k
           0) &&
9176
6.54k
          (quant_params->u_ac_delta_q + cm->seq_params.base_uv_ac_delta_q <=
9177
6.54k
           0) &&
9178
6.52k
          (quant_params->v_ac_delta_q + cm->seq_params.base_uv_ac_delta_q <= 0);
9179
9180
132k
      features->lossless_segment[i] = xd->lossless[i];
9181
132k
      if (xd->lossless[i]) features->has_lossless_segment = 1;
9182
9183
132k
      xd->qindex[i] = qindex;
9184
132k
      if (av2_use_qmatrix(quant_params, xd, i)) {
9185
52.9k
        if (quant_params->qm_index_bits > 0) {
9186
4.93k
          quant_params->qm_index[i] =
9187
4.93k
              avm_rb_read_literal(rb, quant_params->qm_index_bits);
9188
#if CONFIG_QM_DEBUG
9189
          printf("[DEC-FRM] qm_index[%d]: %d\n", i, quant_params->qm_index[i]);
9190
#endif
9191
4.93k
          if (quant_params->qm_index[i] >= quant_params->pic_qm_num) {
9192
178
            avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9193
178
                               "Invalid qm_index[%d]=%d >= %d", i,
9194
178
                               quant_params->qm_index[i],
9195
178
                               quant_params->pic_qm_num);
9196
178
          }
9197
48.0k
        } else {
9198
48.0k
          quant_params->qm_index[i] = 0;
9199
48.0k
        }
9200
52.9k
      }
9201
132k
    }
9202
16.3k
    features->coded_lossless = is_coded_lossless(cm, xd);
9203
16.3k
    features->all_lossless = features->coded_lossless;
9204
9205
    // Decode frame-level TCQ flag, if applicable.
9206
16.3k
    if (features->coded_lossless) {
9207
305
      features->tcq_mode = 0;
9208
16.0k
    } else if (seq_params->enable_tcq >= TCQ_8ST_FR) {
9209
0
      features->tcq_mode = avm_rb_read_bit(rb);
9210
16.0k
    } else {
9211
16.0k
      features->tcq_mode = seq_params->enable_tcq;
9212
16.0k
    }
9213
9214
16.3k
    if (features->coded_lossless || !cm->seq_params.enable_parity_hiding ||
9215
539
        features->tcq_mode)
9216
15.5k
      features->allow_parity_hiding = false;
9217
820
    else
9218
820
      features->allow_parity_hiding = avm_rb_read_bit(rb);
9219
9220
16.3k
    setup_segmentation_dequant(pbi, xd);
9221
9222
16.3k
    if (features->coded_lossless) {
9223
305
      cm->lf.apply_deblocking_filter[0] = 0;
9224
305
      cm->lf.apply_deblocking_filter[1] = 0;
9225
305
    }
9226
16.3k
    if (features->coded_lossless || !seq_params->enable_cdef) {
9227
550
      cm->cdef_info.cdef_frame_enable = 0;
9228
550
    }
9229
16.3k
    if (features->all_lossless || !seq_params->enable_restoration) {
9230
490
      cm->rst_info[0].frame_restoration_type = RESTORE_NONE;
9231
490
      cm->rst_info[1].frame_restoration_type = RESTORE_NONE;
9232
490
      cm->rst_info[2].frame_restoration_type = RESTORE_NONE;
9233
490
      cm->rst_info[0].frame_filters_on = 0;
9234
490
      cm->rst_info[1].frame_filters_on = 0;
9235
490
      cm->rst_info[2].frame_filters_on = 0;
9236
490
    }
9237
16.3k
  } else {
9238
1.99k
    if (cm->seq_params.enable_tip_explicit_qp) {
9239
0
      cm->quant_params.base_qindex = avm_rb_read_literal(
9240
0
          rb, cm->seq_params.bit_depth == AVM_BITS_8 ? QINDEX_BITS_UNEXT
9241
0
                                                     : QINDEX_BITS);
9242
0
      if (av2_num_planes(cm) > 1 && cm->seq_params.uv_ac_delta_q_enabled) {
9243
0
        int diff_uv_delta = 0;
9244
0
        if (cm->seq_params.separate_uv_delta_q) {
9245
0
          diff_uv_delta = avm_rb_read_bit(rb);
9246
0
        }
9247
0
        cm->quant_params.u_ac_delta_q = read_delta_q(rb);
9248
0
        if (diff_uv_delta) {
9249
0
          cm->quant_params.v_ac_delta_q = read_delta_q(rb);
9250
0
        } else {
9251
0
          cm->quant_params.v_ac_delta_q = cm->quant_params.u_ac_delta_q;
9252
0
        }
9253
0
      } else {
9254
0
        cm->quant_params.v_ac_delta_q = cm->quant_params.u_ac_delta_q = 0;
9255
0
      }
9256
0
      cm->cur_frame->base_qindex = cm->quant_params.base_qindex;
9257
0
      cm->cur_frame->u_ac_delta_q = cm->quant_params.u_ac_delta_q;
9258
0
      cm->cur_frame->v_ac_delta_q = cm->quant_params.v_ac_delta_q;
9259
0
    }
9260
1.99k
    features->disable_cdf_update = 1;
9261
1.99k
    features->coded_lossless = 0;
9262
1.99k
    features->all_lossless = 0;
9263
1.99k
  }
9264
18.3k
  setup_loopfilter(cm, rb);
9265
9266
18.3k
  if (!features->coded_lossless && seq_params->enable_gdf) {
9267
15.5k
    setup_gdf(cm, rb);
9268
15.5k
  } else {
9269
2.86k
    cm->gdf_info.gdf_mode = 0;
9270
2.86k
  }
9271
18.3k
  if (!features->coded_lossless && seq_params->enable_cdef) {
9272
15.5k
    setup_cdef(cm, rb);
9273
15.5k
  }
9274
18.3k
  if (!features->all_lossless && seq_params->enable_restoration) {
9275
15.6k
    decode_restoration_mode(cm, rb);
9276
15.6k
  }
9277
45.9k
  for (int plane = 0; plane < CCSO_NUM_COMPONENTS; plane++) {
9278
27.5k
    cm->ccso_info.ccso_enable[plane] = false;
9279
27.5k
  }
9280
18.3k
  if (!features->coded_lossless && seq_params->enable_ccso) {
9281
8.68k
    setup_ccso(cm, rb);
9282
8.68k
  }
9283
18.3k
  if (features->tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
9284
0
    if (cm->seq_params.enable_lf_sub_pu && cm->features.allow_lf_sub_pu &&
9285
0
        cm->lf.apply_deblocking_filter_tip) {
9286
0
      read_tile_info(pbi, rb);
9287
0
    }
9288
0
    setup_film_grain(pbi, rb);
9289
0
    features->enable_imp_msk_bld = seq_params->enable_imp_msk_bld;
9290
    // TIP frame will be output for displaying
9291
    // No futher processing needed
9292
0
    return 0;
9293
0
  }
9294
18.3k
  features->tx_mode = read_tx_mode(rb, features->coded_lossless);
9295
18.3k
  current_frame->reference_mode = read_frame_reference_mode(cm, rb);
9296
9297
18.3k
  av2_setup_skip_mode_allowed(cm);
9298
18.3k
  current_frame->skip_mode_info.skip_mode_flag =
9299
18.3k
      current_frame->skip_mode_info.skip_mode_allowed ? avm_rb_read_bit(rb) : 0;
9300
9301
18.3k
  if (!frame_is_intra_only(cm) && seq_params->enable_bawp)
9302
0
    features->enable_bawp = avm_rb_read_bit(rb);
9303
18.3k
  else
9304
18.3k
    features->enable_bawp = 0;
9305
9306
18.3k
  features->enable_intra_bawp = seq_params->enable_bawp;
9307
9308
18.3k
  features->enable_cwp = seq_params->enable_cwp;
9309
18.3k
  features->allow_warpmv_mode = 0;
9310
18.3k
  if (!frame_is_intra_only(cm) &&
9311
0
      (features->enabled_motion_modes & (1 << WARP_DELTA)) != 0) {
9312
0
    features->allow_warpmv_mode = avm_rb_read_bit(rb);
9313
0
  }
9314
9315
18.3k
  features->enable_imp_msk_bld = seq_params->enable_imp_msk_bld;
9316
9317
18.3k
  features->reduced_tx_set_used = avm_rb_read_literal(rb, 2);
9318
9319
18.3k
  if (features->allow_ref_frame_mvs && !frame_might_allow_ref_frame_mvs(cm)) {
9320
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9321
0
                       "Frame wrongly requests reference frame MVs");
9322
0
  }
9323
9324
18.3k
  if (features->tip_frame_mode && !cm->seq_params.enable_tip) {
9325
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9326
0
                       "Frame wrongly requests TIP mode");
9327
0
  }
9328
9329
18.3k
  if (!frame_is_intra_only(cm)) read_global_motion(cm, rb);
9330
18.3k
  setup_film_grain(pbi, rb);
9331
18.3k
  features->enable_ext_seg = seq_params->enable_ext_seg;
9332
18.3k
  return 0;
9333
18.3k
}
9334
9335
struct avm_read_bit_buffer *av2_init_read_bit_buffer(
9336
    AV2Decoder *pbi, struct avm_read_bit_buffer *rb, const uint8_t *data,
9337
94.2k
    const uint8_t *data_end) {
9338
94.2k
  rb->bit_offset = 0;
9339
94.2k
  rb->error_handler = error_handler;
9340
94.2k
  rb->error_handler_data = &pbi->common;
9341
94.2k
  rb->bit_buffer = data;
9342
94.2k
  rb->bit_buffer_end = data_end;
9343
94.2k
  return rb;
9344
94.2k
}
9345
9346
void av2_read_frame_size(struct avm_read_bit_buffer *rb, int num_bits_width,
9347
8
                         int num_bits_height, int *width, int *height) {
9348
8
  *width = avm_rb_read_literal(rb, num_bits_width) + 1;
9349
8
  *height = avm_rb_read_literal(rb, num_bits_height) + 1;
9350
8
}
9351
61.3k
BITSTREAM_PROFILE av2_read_profile(struct avm_read_bit_buffer *rb) {
9352
61.3k
  int profile = avm_rb_read_literal(rb, PROFILE_BITS);
9353
61.3k
  return (BITSTREAM_PROFILE)profile;
9354
61.3k
}
9355
4.28k
static AVM_INLINE void tip_mode_legal_check(AV2Decoder *const pbi) {
9356
4.28k
  AV2_COMMON *const cm = &pbi->common;
9357
4.28k
  const bool is_tip_frame =
9358
4.28k
      pbi->obu_type == OBU_LEADING_TIP || pbi->obu_type == OBU_REGULAR_TIP;
9359
4.28k
  if (is_tip_frame && cm->features.tip_frame_mode != TIP_FRAME_AS_OUTPUT) {
9360
0
    avm_internal_error(
9361
0
        &cm->error, AVM_CODEC_CORRUPT_FRAME,
9362
0
        "tip_frame_mode is not equal to TIP_FRAME_AS_OUTPUT for a TIP frame");
9363
0
  }
9364
9365
4.28k
  if (is_tip_frame && cm->seq_params.enable_tip != 1) {
9366
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9367
0
                       "enable_tip is not equal to 1 for a TIP frame");
9368
0
  }
9369
9370
4.28k
  if (cm->features.tip_frame_mode == TIP_FRAME_DISABLED) return;
9371
9372
0
  if (cm->current_frame.frame_type == KEY_FRAME ||
9373
0
      cm->current_frame.frame_type == INTRA_ONLY_FRAME ||
9374
0
      cm->current_frame.frame_type == S_FRAME) {
9375
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9376
0
                       "Invalid TIP mode.");
9377
0
  }
9378
9379
0
  if (!cm->features.allow_ref_frame_mvs) {
9380
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9381
0
                       "Invalid TIP mode.");
9382
0
  }
9383
9384
0
  if (!cm->seq_params.enable_tip) {
9385
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9386
0
                       "Invalid TIP mode.");
9387
0
  }
9388
9389
0
  if (!cm->has_both_sides_refs && cm->ref_frames_info.num_past_refs < 2) {
9390
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9391
0
                       "Invalid TIP mode.");
9392
0
  }
9393
9394
0
  TIP *tip_ref = &cm->tip_ref;
9395
0
  if (tip_ref->ref_frame[0] == NONE_FRAME ||
9396
0
      tip_ref->ref_frame[1] == NONE_FRAME) {
9397
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9398
0
                       "Invalid TIP mode.");
9399
0
  }
9400
9401
0
  const int tip_mode_allowed =
9402
0
      tip_ref->ref_frame[0] != NONE_FRAME &&
9403
0
      tip_ref->ref_frame[1] != NONE_FRAME &&
9404
0
      is_ref_motion_field_eligible_by_frame_size(
9405
0
          cm, get_ref_frame_buf(cm, tip_ref->ref_frame[0])) &&
9406
0
      is_ref_motion_field_eligible_by_frame_size(
9407
0
          cm, get_ref_frame_buf(cm, tip_ref->ref_frame[1]));
9408
9409
0
  if (!tip_mode_allowed ||
9410
0
      (!is_ref_motion_field_eligible_by_frame_type(
9411
0
           get_ref_frame_buf(cm, tip_ref->ref_frame[0])) &&
9412
0
       !is_ref_motion_field_eligible_by_frame_type(
9413
0
           get_ref_frame_buf(cm, tip_ref->ref_frame[1])))) {
9414
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9415
0
                       "Invalid TIP mode.");
9416
0
  }
9417
0
}
9418
9419
4.28k
static AVM_INLINE void process_tip_mode(AV2Decoder *pbi) {
9420
4.28k
  AV2_COMMON *const cm = &pbi->common;
9421
4.28k
  const int num_planes = av2_num_planes(cm);
9422
4.28k
  MACROBLOCKD *const xd = &pbi->dcb.xd;
9423
9424
4.28k
  tip_mode_legal_check(pbi);
9425
9426
4.28k
  if (!cm->features.allow_ref_frame_mvs) return;
9427
9428
0
  if (cm->features.tip_frame_mode == TIP_FRAME_DISABLED) {
9429
    // TPL mvs at non-sampled locations will be filled after it is hole-filled
9430
    // and smoothed.
9431
0
    av2_fill_tpl_mvs_sample_gap(cm);
9432
0
    return;
9433
0
  }
9434
9435
0
  if (cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
9436
0
    av2_dec_setup_tip_frame(pbi, cm, xd);
9437
0
  } else if (cm->features.tip_frame_mode == TIP_FRAME_AS_REF) {
9438
0
    av2_setup_tip_motion_field(cm);
9439
0
  }
9440
9441
0
  if (cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
9442
0
    for (int plane = 0; plane < av2_num_planes(cm); plane++) {
9443
0
      cm->cur_frame->ccso_info.ccso_enable[plane] = 0;
9444
0
    }
9445
0
    avm_yv12_copy_frame(&cm->tip_ref.tip_frame->buf, &cm->cur_frame->buf,
9446
0
                        num_planes);
9447
0
    for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
9448
0
      cm->global_motion[i] = default_warp_params;
9449
0
      cm->cur_frame->global_motion[i] = default_warp_params;
9450
0
    }
9451
9452
0
    set_primary_ref_frame_and_ctx(pbi);
9453
0
    cm->seg.enabled = 0;
9454
0
    if (cm->cur_frame->seg_map) {
9455
0
      memset(cm->cur_frame->seg_map, 0,
9456
0
             (cm->cur_frame->mi_rows * cm->cur_frame->mi_cols));
9457
0
    }
9458
0
    memset(&cm->seg, 0, sizeof(cm->seg));
9459
0
    cm->seg.enable_ext_seg = cm->seq_params.enable_ext_seg;
9460
0
    segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
9461
9462
0
    cm->cur_frame->frame_context = *cm->fc;
9463
0
  }
9464
0
}
9465
9466
static int32_t read_tile_indices_in_tilegroup(AV2Decoder *pbi,
9467
                                              struct avm_read_bit_buffer *rb,
9468
4.28k
                                              int *start_tile, int *end_tile) {
9469
4.28k
  AV2_COMMON *const cm = &pbi->common;
9470
4.28k
  CommonTileParams *const tiles = &cm->tiles;
9471
4.28k
  uint32_t saved_bit_offset = rb->bit_offset;
9472
4.28k
  int tile_start_and_end_present_flag = 0;
9473
4.28k
  const int num_tiles = tiles->rows * tiles->cols;
9474
9475
4.28k
  if (num_tiles > 1) {
9476
1.63k
    tile_start_and_end_present_flag = avm_rb_read_bit(rb);
9477
1.63k
  }
9478
4.28k
  if (num_tiles == 1 || !tile_start_and_end_present_flag) {
9479
4.24k
    *start_tile = 0;
9480
4.24k
    *end_tile = num_tiles - 1;
9481
4.24k
  } else {
9482
41
    int tile_bits = tiles->log2_rows + tiles->log2_cols;
9483
41
    *start_tile = avm_rb_read_literal(rb, tile_bits);
9484
41
    *end_tile = avm_rb_read_literal(rb, tile_bits);
9485
41
  }
9486
4.28k
  if (*start_tile != pbi->next_start_tile) {
9487
17
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9488
17
                       "tg_start (%d) must be equal to %d", *start_tile,
9489
17
                       pbi->next_start_tile);
9490
17
    return -1;
9491
17
  }
9492
4.27k
  if (*start_tile > *end_tile) {
9493
0
    avm_internal_error(
9494
0
        &cm->error, AVM_CODEC_CORRUPT_FRAME,
9495
0
        "tg_end (%d) must be greater than or equal to tg_start (%d)", *end_tile,
9496
0
        *start_tile);
9497
0
    return -1;
9498
0
  }
9499
4.27k
  if (*end_tile >= num_tiles) {
9500
0
    avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9501
0
                       "tg_end (%d) must be less than NumTiles (%d)", *end_tile,
9502
0
                       num_tiles);
9503
0
    return -1;
9504
0
  }
9505
4.27k
  pbi->next_start_tile = (*end_tile == num_tiles - 1) ? 0 : *end_tile + 1;
9506
9507
4.27k
  if (cm->bru.enabled) {
9508
0
    if (num_tiles > 1) {
9509
0
      for (int tile_idx = *start_tile; tile_idx <= *end_tile; tile_idx++) {
9510
0
        const int active_bitmap_byte = tile_idx >> 3;
9511
0
        const int active_bitmap_bit = tile_idx & 7;
9512
0
        tiles->tile_active_bitmap[active_bitmap_byte] +=
9513
0
            (avm_rb_read_bit(rb) << active_bitmap_bit);
9514
0
      }
9515
0
    } else {
9516
0
      tiles->tile_active_bitmap[0] = 1;
9517
0
    }
9518
0
  }
9519
4.27k
  return ((rb->bit_offset - saved_bit_offset + 7) >> 3);
9520
4.27k
}
9521
9522
int32_t av2_read_tilegroup_header(
9523
    AV2Decoder *pbi, struct avm_read_bit_buffer *rb, const uint8_t *data,
9524
    const uint8_t **p_data_end, int *first_tile_group_in_frame, int *start_tile,
9525
18.4k
    int *end_tile, OBU_TYPE obu_type, int obu_xlayer_id) {
9526
#if CONFIG_COLLECT_COMPONENT_TIMING
9527
  start_timing(pbi, av2_read_tilegroup_header_time);
9528
#endif
9529
9530
18.4k
  assert(rb->bit_offset == 0);
9531
9532
18.4k
  AV2_COMMON *const cm = &pbi->common;
9533
18.4k
  MACROBLOCKD *const xd = &pbi->dcb.xd;
9534
9535
18.4k
  int is_first_tile_group = 1;
9536
18.4k
  int send_uncompressed_header_flag = 1;
9537
18.4k
  bool send_first_tile_group_indication = true;
9538
18.4k
  send_first_tile_group_indication &= obu_type != OBU_LEADING_SEF;
9539
18.4k
  send_first_tile_group_indication &= obu_type != OBU_REGULAR_SEF;
9540
18.4k
  send_first_tile_group_indication &= obu_type != OBU_LEADING_TIP;
9541
18.4k
  send_first_tile_group_indication &= obu_type != OBU_REGULAR_TIP;
9542
18.4k
  send_first_tile_group_indication &= obu_type != OBU_BRIDGE_FRAME;
9543
18.4k
  if (send_first_tile_group_indication)
9544
18.0k
    is_first_tile_group = avm_rb_read_bit(rb);
9545
  // It is a requirement of bitstream conformance that SeenFrameHeader is not
9546
  // equal to is_first_tile_group.
9547
18.4k
  if (pbi->seen_frame_header == is_first_tile_group) {
9548
35
    avm_internal_error(
9549
35
        &cm->error, AVM_CODEC_CORRUPT_FRAME,
9550
35
        "SeenFrameHeader (%d) is equal to is_first_tile_group (%d)",
9551
35
        pbi->seen_frame_header, is_first_tile_group);
9552
35
  }
9553
18.4k
  *first_tile_group_in_frame = is_first_tile_group;
9554
9555
18.4k
  if (is_first_tile_group) {
9556
#if CONFIG_MISMATCH_DEBUG
9557
    mismatch_move_frame_idx_r(1);
9558
#endif  // CONFIG_MISMATCH_DEBUG
9559
18.3k
    pbi->seen_frame_header = 1;
9560
147k
    for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
9561
128k
      cm->global_motion[i] = default_warp_params;
9562
128k
      cm->cur_frame->global_motion[i] = default_warp_params;
9563
128k
    }
9564
9565
73.5k
    for (int p = 0; p < MAX_MB_PLANE; ++p) {
9566
55.1k
      cm->cur_frame->rst_info[p].frame_filters_on = 0;
9567
55.1k
    }
9568
9569
18.3k
    xd->global_motion = cm->global_motion;
9570
18.3k
  } else {
9571
35
    send_uncompressed_header_flag = avm_rb_read_bit(rb);
9572
35
  }
9573
9574
18.4k
  if (send_uncompressed_header_flag) {
9575
18.3k
    if (!is_first_tile_group) {
9576
0
      rb->bit_offset += pbi->uncomp_hdr_size_in_bits;
9577
18.3k
    } else {
9578
18.3k
      uint32_t uncomp_hdr_start_point = rb->bit_offset;
9579
18.3k
      read_uncompressed_header(pbi, obu_type, obu_xlayer_id, rb);
9580
9581
      // Conformance check for the number of reference frames
9582
18.3k
      if (cm->seq_params.seq_max_level_idx < SEQ_LEVELS) {
9583
4.24k
        const int max_legal_ref_frames = av2_get_max_level_ref_frames(
9584
4.24k
            cm, obu_type, cm->seq_params.seq_max_level_idx);
9585
4.24k
        if (cm->seq_params.ref_frames > max_legal_ref_frames) {
9586
0
          avm_internal_error(
9587
0
              &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
9588
0
              "The maximum number of reference frames shall not be "
9589
0
              "greater than %d, yet the bitstream indicates that the "
9590
0
              "maximum decoded picture buffer size is equal to %d.\n",
9591
0
              max_legal_ref_frames, cm->seq_params.ref_frames);
9592
0
        }
9593
4.24k
      }
9594
9595
18.3k
      pbi->uncomp_hdr_size_in_bits = rb->bit_offset - uncomp_hdr_start_point;
9596
18.3k
    }
9597
18.3k
  }
9598
9599
18.4k
  if (is_first_tile_group) {
9600
#if CONFIG_BITSTREAM_DEBUG
9601
    avm_bitstream_queue_set_frame_read(
9602
        (int)(derive_output_order_idx(cm, cm->cur_frame) * 2 +
9603
              cm->immediate_output_picture));
9604
#endif
9605
9606
    // avm_rb_bytes_read()= (rb->bit_offset + 7) >> 3;
9607
4.28k
    const uint32_t uncomp_hdr_size =
9608
4.28k
        (uint32_t)avm_rb_bytes_read(rb);  // Size of the uncompressed header
9609
4.28k
    const YV12_BUFFER_CONFIG *new_fb =
9610
4.28k
        (cm->show_existing_frame && !cm->derive_sef_order_hint)
9611
4.28k
            ? &cm->ref_frame_map[cm->sef_ref_fb_idx]->buf
9612
4.28k
            : &cm->cur_frame->buf;
9613
4.28k
    xd->cur_buf = new_fb;
9614
4.28k
    if (av2_allow_intrabc(cm, xd, BLOCK_4X4) && xd->tree_type != CHROMA_PART) {
9615
4.25k
      av2_setup_scale_factors_for_frame(
9616
4.25k
          &cm->sf_identity, xd->cur_buf->y_crop_width,
9617
4.25k
          xd->cur_buf->y_crop_height, xd->cur_buf->y_crop_width,
9618
4.25k
          xd->cur_buf->y_crop_height);
9619
4.25k
    }
9620
4.28k
    if (obu_type == OBU_REGULAR_SEF || obu_type == OBU_LEADING_SEF) {
9621
      // showing a frame directly
9622
0
      *p_data_end = data + uncomp_hdr_size;
9623
0
      if (pbi->reset_decoder_state) {
9624
        // Use the default frame context values.
9625
0
        *cm->fc = *cm->default_frame_context;
9626
0
        if (!cm->fc->initialized)
9627
0
          avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9628
0
                             "Uninitialized entropy context.");
9629
0
      }
9630
#if CONFIG_COLLECT_COMPONENT_TIMING
9631
      end_timing(pbi, av2_read_tilegroup_header_time);
9632
#endif
9633
0
      return uncomp_hdr_size;
9634
0
    }
9635
9636
4.28k
    cm->mi_params.setup_mi(&cm->mi_params);
9637
9638
4.28k
    av2_setup_block_planes(xd, cm->seq_params.subsampling_x,
9639
4.28k
                           cm->seq_params.subsampling_y, av2_num_planes(cm));
9640
9641
4.28k
    av2_setup_ref_frame_sides(cm);
9642
4.28k
    if (cm->features.allow_ref_frame_mvs) av2_setup_motion_field(cm);
9643
9644
4.28k
    if (cm->bru.frame_inactive_flag || cm->bridge_frame_info.is_bridge_frame) {
9645
0
      for (int plane = 0; plane < av2_num_planes(cm); plane++) {
9646
0
        cm->cur_frame->ccso_info.ccso_enable[plane] = 0;
9647
0
      }
9648
0
      MV_REF *frame_mvs = cm->cur_frame->mvs;
9649
0
      const int mvs_rows =
9650
0
          ROUND_POWER_OF_TWO(cm->mi_params.mi_rows, TMVP_SHIFT_BITS);
9651
0
      const int mvs_cols =
9652
0
          ROUND_POWER_OF_TWO(cm->mi_params.mi_cols, TMVP_SHIFT_BITS);
9653
0
      const int mvs_stride = mvs_cols;
9654
9655
0
      for (int h = 0; h < mvs_rows; h++) {
9656
0
        MV_REF *mv = frame_mvs;
9657
0
        for (int w = 0; w < mvs_cols; w++) {
9658
0
          if (cm->bridge_frame_info.is_bridge_frame) {
9659
0
            mv->ref_frame[0] =
9660
0
                cm->bridge_frame_info.bridge_frame_ref_idx_remapped;
9661
0
          } else {
9662
0
            mv->ref_frame[0] = cm->bru.update_ref_idx;
9663
0
          }
9664
0
          mv->ref_frame[1] = NONE_FRAME;
9665
0
          mv->mv[0].as_int = 0;
9666
0
          mv->mv[1].as_int = 0;
9667
0
          mv++;
9668
0
        }
9669
0
        frame_mvs += mvs_stride;
9670
0
      }
9671
0
      for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
9672
0
        cm->global_motion[i] = default_warp_params;
9673
0
        cm->cur_frame->global_motion[i] = default_warp_params;
9674
0
      }
9675
9676
0
      set_primary_ref_frame_and_ctx(pbi);
9677
0
      cm->seg.enabled = 0;
9678
0
      if (cm->cur_frame->seg_map) {
9679
0
        memset(cm->cur_frame->seg_map, 0,
9680
0
               (cm->cur_frame->mi_rows * cm->cur_frame->mi_cols));
9681
0
      }
9682
0
      memset(&cm->seg, 0, sizeof(cm->seg));
9683
0
      cm->seg.enable_ext_seg = cm->seq_params.enable_ext_seg;
9684
0
      segfeatures_copy(&cm->cur_frame->seg, &cm->seg);
9685
0
      if (cm->features.primary_ref_frame == PRIMARY_REF_NONE ||
9686
0
          cm->features.cross_frame_context == CROSS_FRAME_CONTEXT_DISABLED) {
9687
        // use the default frame context values
9688
0
        *cm->fc = *cm->default_frame_context;
9689
0
      } else {
9690
0
        *cm->fc = get_primary_ref_frame_buf(cm, cm->features.primary_ref_frame)
9691
0
                      ->frame_context;
9692
0
        int ref_frame_used = PRIMARY_REF_NONE;
9693
0
        int map_idx = INVALID_IDX;
9694
0
        get_secondary_reference_frame_idx(cm, &ref_frame_used, &map_idx);
9695
0
        avg_primary_secondary_references(cm, ref_frame_used, map_idx);
9696
0
      }
9697
0
      *p_data_end = data + uncomp_hdr_size;
9698
#if CONFIG_COLLECT_COMPONENT_TIMING
9699
      end_timing(pbi, av2_read_tilegroup_header_time);
9700
#endif
9701
0
      return uncomp_hdr_size;
9702
0
    }
9703
9704
4.28k
    process_tip_mode(pbi);
9705
4.28k
    if (obu_type == OBU_REGULAR_TIP || obu_type == OBU_LEADING_TIP) {
9706
0
      *p_data_end = data + uncomp_hdr_size;
9707
#if CONFIG_COLLECT_COMPONENT_TIMING
9708
      end_timing(pbi, av2_read_tilegroup_header_time);
9709
#endif
9710
0
      return uncomp_hdr_size;
9711
0
    }
9712
9713
4.28k
    if (cm->features.primary_ref_frame == PRIMARY_REF_NONE ||
9714
4.28k
        cm->features.cross_frame_context == CROSS_FRAME_CONTEXT_DISABLED) {
9715
      // use the default frame context values
9716
4.28k
      *cm->fc = *cm->default_frame_context;
9717
4.28k
    } else {
9718
0
      *cm->fc = get_primary_ref_frame_buf(cm, cm->features.primary_ref_frame)
9719
0
                    ->frame_context;
9720
0
      int ref_frame_used = PRIMARY_REF_NONE;
9721
0
      int map_idx = INVALID_IDX;
9722
0
      get_secondary_reference_frame_idx(cm, &ref_frame_used, &map_idx);
9723
0
      avg_primary_secondary_references(cm, ref_frame_used, map_idx);
9724
0
    }
9725
4.28k
    if (!cm->fc->initialized)
9726
0
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
9727
0
                         "Uninitialized entropy context.");
9728
9729
4.28k
    pbi->dcb.corrupted = 0;
9730
4.28k
  }
9731
9732
18.4k
  bool tile_indices_present_flag = true;
9733
18.4k
  tile_indices_present_flag &= obu_type != OBU_LEADING_SEF;
9734
18.4k
  tile_indices_present_flag &= obu_type != OBU_REGULAR_SEF;
9735
18.4k
  tile_indices_present_flag &= obu_type != OBU_LEADING_TIP;
9736
18.4k
  tile_indices_present_flag &= obu_type != OBU_REGULAR_TIP;
9737
18.4k
  tile_indices_present_flag &=
9738
18.4k
      (!cm->bru.frame_inactive_flag && !cm->bridge_frame_info.is_bridge_frame);
9739
18.4k
  if (tile_indices_present_flag)
9740
4.28k
    read_tile_indices_in_tilegroup(pbi, rb, start_tile, end_tile);
9741
#if CONFIG_COLLECT_COMPONENT_TIMING
9742
  end_timing(pbi, av2_read_tilegroup_header_time);
9743
#endif
9744
18.4k
  return (int32_t)avm_rb_bytes_read(rb);
9745
18.4k
}
9746
9747
// Once-per-frame initialization
9748
3.71k
static AVM_INLINE void setup_frame_info(AV2Decoder *pbi) {
9749
3.71k
  AV2_COMMON *const cm = &pbi->common;
9750
9751
3.71k
  if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
9752
2.33k
      cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
9753
2.18k
      cm->rst_info[2].frame_restoration_type != RESTORE_NONE) {
9754
1.55k
    av2_alloc_restoration_buffers(cm);
9755
2.16k
  } else {
9756
2.16k
    if (cm->gdf_info.gdf_mode) {
9757
1.86k
      av2_alloc_restoration_boundary_buffers(cm, 1);
9758
1.86k
    }
9759
2.16k
  }
9760
3.71k
  const int buf_size = MC_TEMP_BUF_PELS << 1;
9761
3.71k
  if (pbi->td.mc_buf_size != buf_size) {
9762
1.94k
    av2_free_mc_tmp_buf(&pbi->td);
9763
1.94k
    av2_free_opfl_tmp_bufs(&pbi->td);
9764
9765
1.94k
    allocate_mc_tmp_buf(cm, &pbi->td, buf_size);
9766
1.94k
    allocate_opfl_tmp_bufs(cm, &pbi->td);
9767
1.94k
  }
9768
3.71k
}
9769
9770
// 1) For multiple tiles-based coding, calculate the average CDFs from the
9771
// allowed tiles, and use the average CDFs of the tiles as the frame's CDFs
9772
// 2) For one tile coding, directly use that tile's CDFs as the frame's CDFs
9773
0
void decoder_avg_tiles_cdfs(AV2Decoder *const pbi) {
9774
0
  AV2_COMMON *const cm = &pbi->common;
9775
0
  const CommonTileParams *const tiles = &cm->tiles;
9776
0
  const int total_tiles = tiles->rows * tiles->cols;
9777
0
  if (total_tiles == 1) {
9778
0
    *cm->fc = pbi->tile_data[0].tctx;
9779
0
  } else {
9780
0
    const unsigned int total_tiles_log2 = av2_compute_allowed_tiles_log2(cm);
9781
0
    const unsigned int used_tiles = (1 << total_tiles_log2);
9782
0
    *cm->fc = pbi->tile_data[0].tctx;
9783
0
    av2_shift_cdf_symbols(cm->fc, total_tiles_log2);
9784
0
    for (unsigned int tile_idx = 1; tile_idx < used_tiles; ++tile_idx) {
9785
0
      av2_cumulative_avg_cdf_symbols(cm->fc, &pbi->tile_data[tile_idx].tctx,
9786
0
                                     total_tiles_log2);
9787
0
    }
9788
0
  }
9789
0
}
9790
9791
38
void av2_gdf_frame_dec(AV2_COMMON *cm) { gdf_filter_frame(cm); }
9792
9793
void av2_decode_tg_tiles_and_wrapup(AV2Decoder *pbi, const uint8_t *data,
9794
                                    const uint8_t *data_end,
9795
                                    const uint8_t **p_data_end, int start_tile,
9796
3.71k
                                    int end_tile, int initialize_flag) {
9797
#if CONFIG_COLLECT_COMPONENT_TIMING
9798
  start_timing(pbi, av2_decode_tg_tiles_and_wrapup_time);
9799
#endif
9800
9801
3.71k
  AV2_COMMON *const cm = &pbi->common;
9802
3.71k
  CommonTileParams *const tiles = &cm->tiles;
9803
3.71k
  MACROBLOCKD *const xd = &pbi->dcb.xd;
9804
3.71k
  const int tile_count_tg = end_tile - start_tile + 1;
9805
9806
3.71k
  if (!cm->wedge_mask_initialized &&
9807
3.71k
      cm->current_frame.frame_type != KEY_FRAME) {
9808
0
    av2_init_wedge_masks();
9809
0
    cm->wedge_mask_initialized = true;
9810
0
  }
9811
3.71k
  if (initialize_flag) setup_frame_info(pbi);
9812
3.71k
  const int num_planes = av2_num_planes(cm);
9813
#if CONFIG_INSPECTION
9814
  avm_realloc_frame_buffer(
9815
      &cm->predicted_pixels, cm->width, cm->height,
9816
      cm->seq_params.subsampling_x, cm->seq_params.subsampling_y,
9817
      AVM_DEC_BORDER_IN_PIXELS, cm->features.byte_alignment, NULL, NULL, NULL,
9818
      false);
9819
  avm_realloc_frame_buffer(
9820
      &cm->prefiltered_pixels, cm->width, cm->height,
9821
      cm->seq_params.subsampling_x, cm->seq_params.subsampling_y,
9822
      AVM_DEC_BORDER_IN_PIXELS, cm->features.byte_alignment, NULL, NULL, NULL,
9823
      false);
9824
#endif  // CONFIG_INSPECTION
9825
3.71k
  if (pbi->max_threads > 1 && pbi->row_mt)
9826
0
    *p_data_end =
9827
0
        decode_tiles_row_mt(pbi, data, data_end, start_tile, end_tile);
9828
3.71k
  else if (pbi->max_threads > 1 && tile_count_tg > 1)
9829
1.57k
    *p_data_end = decode_tiles_mt(pbi, data, data_end, start_tile, end_tile);
9830
2.14k
  else
9831
2.14k
    *p_data_end = decode_tiles(pbi, data, data_end, start_tile, end_tile);
9832
9833
  // If the bit stream is monochrome, set the U and V buffers to a constant.
9834
3.71k
  if (num_planes < 3) {
9835
0
    set_planes_to_neutral_grey(&cm->seq_params, xd->cur_buf, 1);
9836
0
  }
9837
9838
#if CONFIG_INSPECTION
9839
  memcpy(cm->prefiltered_pixels.buffer_alloc, cm->cur_frame->buf.buffer_alloc,
9840
         cm->prefiltered_pixels.frame_size);
9841
#endif  // CONFIG_INSPECTION
9842
9843
3.71k
  if (end_tile != tiles->rows * tiles->cols - 1) {
9844
0
    return;
9845
0
  }
9846
9847
3.71k
  av2_alloc_cdef_buffers(cm, &pbi->cdef_worker, &pbi->cdef_sync,
9848
3.71k
                         pbi->num_workers);
9849
3.71k
  av2_alloc_cdef_sync(cm, &pbi->cdef_sync, pbi->num_workers);
9850
9851
  // verify active region
9852
3.71k
  if (!bru_active_map_validation(cm)) {
9853
0
    avm_internal_error(&cm->error, AVM_CODEC_ERROR, "Invalid active region");
9854
0
  }
9855
  // bru swap in mode 0, in mode 1, still use cur frame and then drop bru ref
9856
  // after filtering
9857
  // backward reference frame update
9858
  // check if any active block
9859
  // 1. intra frames do not have backward update
9860
  // 2. if no active block in the frame and bru enabled, no need to update, just
9861
  // drop the recon
9862
  // 3. if any inactive block exists and bru enabled, update ref and drop the
9863
  // if enabled flag signaled == 1, do swap
9864
3.71k
  if (cm->bru.enabled && pbi->bru_opt_mode &&
9865
0
      cm->current_frame.frame_type != KEY_FRAME) {
9866
0
    dec_bru_swap_stage(cm, xd);
9867
0
    if (cm->bru.frame_inactive_flag) {
9868
0
      cm->cur_frame->frame_context = *cm->fc;
9869
#if CONFIG_PARAKIT_COLLECT_DATA
9870
      for (int i = 0; i < MAX_NUM_CTX_GROUPS; i++)
9871
        for (int j = 0; j < MAX_DIMS_CONTEXT3; j++)
9872
          for (int k = 0; k < MAX_DIMS_CONTEXT2; k++)
9873
            for (int l = 0; l < MAX_DIMS_CONTEXT1; l++)
9874
              for (int h = 0; h < MAX_DIMS_CONTEXT0; h++)
9875
                beginningFrameFlag[i][j][k][l][h] = 1;
9876
#endif
9877
0
      return;
9878
0
    }
9879
0
  }
9880
9881
3.71k
  if (!cm->bru.frame_inactive_flag) {
9882
53
    if (cm->lf.apply_deblocking_filter[0] ||
9883
32
        cm->lf.apply_deblocking_filter[1]) {
9884
32
      if (pbi->num_workers > 1) {
9885
0
        av2_loop_filter_frame_mt(&cm->cur_frame->buf, cm, &pbi->dcb.xd, 0,
9886
0
                                 num_planes, 0, pbi->tile_workers,
9887
0
                                 pbi->num_workers, &pbi->lf_row_sync);
9888
32
      } else {
9889
32
        av2_loop_filter_frame(&cm->cur_frame->buf, cm, &pbi->dcb.xd, 0,
9890
32
                              num_planes, 0);
9891
32
      }
9892
#if CONFIG_MISMATCH_DEBUG
9893
      mismatch_check_frame(&cm->cur_frame->buf,
9894
                           cm->current_frame.display_order_hint, num_planes, 0);
9895
#endif
9896
32
    }
9897
9898
53
    const int use_ccso =
9899
53
        !pbi->skip_loop_filter && !cm->features.coded_lossless &&
9900
52
        (cm->ccso_info.ccso_enable[0] || cm->ccso_info.ccso_enable[1] ||
9901
28
         cm->ccso_info.ccso_enable[2]);
9902
53
    uint16_t *ext_rec_y = NULL;
9903
53
    if (use_ccso) {
9904
28
      const int pic_height = cm->cur_frame->buf.y_height;
9905
28
      const int pic_width = cm->cur_frame->buf.y_width;
9906
28
      const int dst_stride = cm->cur_frame->buf.y_stride;
9907
28
      const uint16_t *rec_y = cm->cur_frame->buf.y_buffer;
9908
28
      const int ccso_stride_ext = pic_width + (CCSO_PADDING_SIZE << 1);
9909
28
      ext_rec_y = avm_malloc(sizeof(*ext_rec_y) *
9910
28
                             (pic_height + (CCSO_PADDING_SIZE << 1)) *
9911
28
                             (pic_width + (CCSO_PADDING_SIZE << 1)));
9912
75.1k
      for (int r = 0; r < pic_height; ++r) {
9913
19.6M
        for (int c = 0; c < pic_width; ++c) {
9914
19.5M
          ext_rec_y[(r + CCSO_PADDING_SIZE) * ccso_stride_ext + c +
9915
19.5M
                    CCSO_PADDING_SIZE] = rec_y[r * dst_stride + c];
9916
19.5M
        }
9917
75.0k
      }
9918
28
      extend_ccso_border(&cm->cur_frame->buf, ext_rec_y, CCSO_PADDING_SIZE);
9919
28
    }
9920
9921
53
    const int do_loop_restoration =
9922
53
        cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
9923
46
        (cm->rst_info[1].frame_restoration_type != RESTORE_NONE &&
9924
6
         !cm->seq_params.monochrome) ||
9925
40
        (cm->rst_info[2].frame_restoration_type != RESTORE_NONE &&
9926
0
         !cm->seq_params.monochrome);
9927
53
    const int do_cdef = !pbi->skip_loop_filter &&
9928
53
                        !cm->features.coded_lossless &&
9929
52
                        cm->cdef_info.cdef_frame_enable;
9930
53
    const int do_gdf = is_gdf_enabled(cm);
9931
53
    const int optimized_loop_restoration =
9932
53
        !cm->seq_params.disable_loopfilters_across_tiles && !do_gdf &&
9933
12
        !use_ccso && !do_cdef;
9934
9935
53
    if (!optimized_loop_restoration) {
9936
53
      if (do_loop_restoration)
9937
13
        av2_loop_restoration_save_boundary_lines(&pbi->common.cur_frame->buf,
9938
13
                                                 cm, 0);
9939
40
      else {
9940
40
        if (do_gdf)
9941
34
          save_tile_row_boundary_lines(&pbi->common.cur_frame->buf, 0, cm, 0);
9942
40
      }
9943
9944
53
      if (do_cdef) {
9945
40
        if (pbi->num_workers > 1 &&
9946
0
            !cm->seq_params.disable_loopfilters_across_tiles) {
9947
0
          av2_cdef_frame_mt(cm, &pbi->dcb.xd, pbi->cdef_worker,
9948
0
                            pbi->tile_workers, &pbi->cdef_sync,
9949
0
                            pbi->num_workers, av2_cdef_init_fb_row_mt);
9950
40
        } else {
9951
40
          av2_cdef_frame(&pbi->common.cur_frame->buf, cm, &pbi->dcb.xd,
9952
40
                         av2_cdef_init_fb_row);
9953
40
        }
9954
40
      }
9955
#if CONFIG_MISMATCH_DEBUG
9956
      mismatch_check_frame(&pbi->common.cur_frame->buf,
9957
                           cm->current_frame.display_order_hint, num_planes, 1);
9958
#endif
9959
53
      if (use_ccso) {
9960
28
        if (pbi->num_workers > 1 &&
9961
0
            !cm->seq_params.disable_loopfilters_across_tiles) {
9962
0
          av2_ccso_frame_mt(&cm->cur_frame->buf, cm, xd, pbi->tile_workers,
9963
0
                            pbi->num_workers, ext_rec_y, &pbi->ccso_sync);
9964
28
        } else {
9965
28
          ccso_frame(&cm->cur_frame->buf, cm, xd, ext_rec_y);
9966
28
        }
9967
28
        avm_free(ext_rec_y);
9968
28
      }
9969
#if CONFIG_MISMATCH_DEBUG
9970
      mismatch_check_frame(&pbi->common.cur_frame->buf,
9971
                           cm->current_frame.display_order_hint, num_planes, 2);
9972
#endif
9973
53
      if (do_gdf) {
9974
38
        gdf_copy_guided_frame(cm);
9975
38
      }
9976
53
      if (do_loop_restoration) {
9977
13
        av2_loop_restoration_save_boundary_lines(&pbi->common.cur_frame->buf,
9978
13
                                                 cm, 1);
9979
40
      } else {
9980
40
        if (do_gdf)
9981
34
          save_tile_row_boundary_lines(&pbi->common.cur_frame->buf, 0, cm, 1);
9982
40
      }
9983
53
      if (do_loop_restoration) {
9984
13
        copy_frame_filters_to_runits_if_needed(cm);
9985
13
        if (pbi->num_workers > 1 &&
9986
0
            !cm->seq_params.disable_loopfilters_across_tiles) {
9987
0
          av2_loop_restoration_filter_frame_mt(
9988
0
              (YV12_BUFFER_CONFIG *)xd->cur_buf, cm, optimized_loop_restoration,
9989
0
              pbi->tile_workers, pbi->num_workers, &pbi->lr_row_sync,
9990
0
              &pbi->lr_ctxt);
9991
13
        } else {
9992
13
          av2_loop_restoration_filter_frame((YV12_BUFFER_CONFIG *)xd->cur_buf,
9993
13
                                            cm, optimized_loop_restoration,
9994
13
                                            &pbi->lr_ctxt);
9995
13
        }
9996
#if CONFIG_MISMATCH_DEBUG
9997
        mismatch_check_frame(&pbi->common.cur_frame->buf,
9998
                             cm->current_frame.display_order_hint, num_planes,
9999
                             3);
10000
#endif
10001
13
      }
10002
53
      if (do_gdf) {
10003
38
        av2_gdf_frame_dec(cm);
10004
#if CONFIG_MISMATCH_DEBUG
10005
        mismatch_check_frame(&pbi->common.cur_frame->buf,
10006
                             cm->current_frame.display_order_hint, num_planes,
10007
                             4);
10008
#endif
10009
38
        gdf_free_guided_frame(cm);
10010
38
      }
10011
10012
53
    } else {
10013
0
      if (do_loop_restoration) {
10014
0
        copy_frame_filters_to_runits_if_needed(cm);
10015
0
        if (pbi->num_workers > 1 &&
10016
0
            !cm->seq_params.disable_loopfilters_across_tiles) {
10017
0
          av2_loop_restoration_filter_frame_mt(
10018
0
              (YV12_BUFFER_CONFIG *)xd->cur_buf, cm, optimized_loop_restoration,
10019
0
              pbi->tile_workers, pbi->num_workers, &pbi->lr_row_sync,
10020
0
              &pbi->lr_ctxt);
10021
0
        } else {
10022
0
          av2_loop_restoration_filter_frame((YV12_BUFFER_CONFIG *)xd->cur_buf,
10023
0
                                            cm, optimized_loop_restoration,
10024
0
                                            &pbi->lr_ctxt);
10025
0
        }
10026
#if CONFIG_MISMATCH_DEBUG
10027
        mismatch_check_frame(&pbi->common.cur_frame->buf,
10028
                             cm->current_frame.display_order_hint, num_planes,
10029
                             3);
10030
#endif
10031
0
      }
10032
0
    }
10033
10034
53
    if (!pbi->dcb.corrupted) {
10035
53
      if (!cm->bridge_frame_info.is_bridge_frame) {
10036
53
        if (cm->seq_params.enable_avg_cdf && cm->seq_params.avg_cdf_type &&
10037
52
            cm->tiles.rows * cm->tiles.cols > 1) {
10038
0
          decoder_avg_tiles_cdfs(pbi);
10039
53
        } else {
10040
53
          assert(pbi->context_update_tile_id < pbi->allocated_tiles);
10041
53
          *cm->fc = pbi->tile_data[pbi->context_update_tile_id].tctx;
10042
53
        }
10043
53
        av2_reset_cdf_symbol_counters(cm->fc);
10044
53
      }
10045
53
    } else {
10046
0
      avm_internal_error(&cm->error, AVM_CODEC_CORRUPT_FRAME,
10047
0
                         "Decode failed. Frame data is corrupted.");
10048
0
    }
10049
53
  }
10050
10051
#if CONFIG_INSPECTION
10052
  if (pbi->inspect_cb != NULL) {
10053
    (*pbi->inspect_cb)(pbi, pbi->inspect_ctx);
10054
  }
10055
#endif  // CONFIG_INSPECTION
10056
10057
  // Non frame parallel update frame context here.
10058
3.71k
  cm->cur_frame->frame_context = *cm->fc;
10059
#if CONFIG_PARAKIT_COLLECT_DATA
10060
  for (int i = 0; i < MAX_NUM_CTX_GROUPS; i++)
10061
    for (int j = 0; j < MAX_DIMS_CONTEXT3; j++)
10062
      for (int k = 0; k < MAX_DIMS_CONTEXT2; k++)
10063
        for (int l = 0; l < MAX_DIMS_CONTEXT1; l++)
10064
          for (int h = 0; h < MAX_DIMS_CONTEXT0; h++)
10065
            beginningFrameFlag[i][j][k][l][h] = 1;
10066
#endif
10067
10068
#if CONFIG_COLLECT_COMPONENT_TIMING
10069
  end_timing(pbi, av2_decode_tg_tiles_and_wrapup_time);
10070
#endif
10071
3.71k
}