Coverage Report

Created: 2026-10-17 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/avm/av2/decoder/decoder.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 <limits.h>
15
#include <stdio.h>
16
17
#include "config/av2_rtcd.h"
18
#include "config/avm_dsp_rtcd.h"
19
#include "config/avm_scale_rtcd.h"
20
21
#include "avm_dsp/avm_dsp_common.h"
22
#include "avm_mem/avm_mem.h"
23
#include "avm_ports/system_state.h"
24
#include "avm_ports/avm_once.h"
25
#include "avm_ports/avm_timer.h"
26
#include "avm_scale/avm_scale.h"
27
#include "avm_util/avm_thread.h"
28
#if CONFIG_MISMATCH_DEBUG
29
#include "avm_util/debug_util.h"
30
#endif  // CONFIG_MISMATCH_DEBUG
31
32
#include "av2/common/alloccommon.h"
33
#include "av2/common/av2_common_int.h"
34
#include "av2/common/av2_loopfilter.h"
35
#include "av2/common/bru.h"
36
#include "av2/common/pred_common.h"
37
#include "av2/common/quant_common.h"
38
#include "av2/common/reconinter.h"
39
#include "av2/common/reconintra.h"
40
41
#include "av2/decoder/decodeframe.h"
42
#include "av2/decoder/decoder.h"
43
#include "av2/decoder/detokenize.h"
44
#include "av2/decoder/obu.h"
45
46
#if CONFIG_PARAKIT_COLLECT_DATA
47
#include "av2/common/entropy_sideinfo.h"
48
int beginningFrameFlag[MAX_NUMBER_CONTEXTS][MAX_DIMS_CONTEXT3]
49
                      [MAX_DIMS_CONTEXT2][MAX_DIMS_CONTEXT1][MAX_DIMS_CONTEXT0];
50
#endif
51
52
1
static void initialize_dec(void) {
53
1
  av2_rtcd();
54
1
  avm_dsp_rtcd();
55
1
  avm_scale_rtcd();
56
1
  av2_init_intra_predictors();
57
1
  av2_init_stxfm_kernels();
58
1
}
59
60
static void update_subgop_stats(const AV2_COMMON *const cm,
61
                                SubGOPStatsDec *const subgop_stats,
62
                                unsigned int display_order_hint,
63
463
                                unsigned int enable_subgop_stats) {
64
463
  if (!enable_subgop_stats) return;
65
  // Update subgop related frame data.
66
0
  subgop_stats->disp_frame_idx[subgop_stats->stat_count] = display_order_hint;
67
0
  subgop_stats->show_existing_frame[subgop_stats->stat_count] =
68
0
      cm->show_existing_frame;
69
0
  subgop_stats->immediate_output_picture[subgop_stats->stat_count] =
70
0
      cm->immediate_output_picture;
71
0
  subgop_stats->qindex[subgop_stats->stat_count] = cm->quant_params.base_qindex;
72
0
  subgop_stats->refresh_frame_flags[subgop_stats->stat_count] =
73
0
      cm->current_frame.refresh_frame_flags;
74
0
  for (MV_REFERENCE_FRAME ref_frame = 0; ref_frame < cm->seq_params.ref_frames;
75
0
       ++ref_frame)
76
0
    if (cm->ref_frame_map[ref_frame] != NULL) {
77
0
      subgop_stats->ref_frame_map[subgop_stats->stat_count][ref_frame] =
78
0
          cm->ref_frame_map[ref_frame]->order_hint;
79
0
    } else {
80
0
      subgop_stats->ref_frame_map[subgop_stats->stat_count][ref_frame] = 0;
81
0
    }
82
83
0
  assert(subgop_stats->stat_count < MAX_SUBGOP_STATS_SIZE);
84
0
  subgop_stats->stat_count++;
85
0
}
86
87
static void dec_set_mb_mi(CommonModeInfoParams *mi_params, int width,
88
13.3k
                          int height) {
89
  // Ensure that the decoded width and height are both multiples of
90
  // 8 luma pixels (note: this may only be a multiple of 4 chroma pixels if
91
  // subsampling is used).
92
  // This simplifies the implementation of various experiments,
93
  // eg. cdef, which operates on units of 8x8 luma pixels.
94
13.3k
  const int aligned_width = ALIGN_POWER_OF_TWO(width, 3);
95
13.3k
  const int aligned_height = ALIGN_POWER_OF_TWO(height, 3);
96
97
13.3k
  mi_params->mi_cols = aligned_width >> MI_SIZE_LOG2;
98
13.3k
  mi_params->mi_rows = aligned_height >> MI_SIZE_LOG2;
99
13.3k
  mi_params->mi_stride = calc_mi_size(mi_params->mi_cols);
100
101
13.3k
  mi_params->mb_cols = (mi_params->mi_cols + 2) >> 2;
102
13.3k
  mi_params->mb_rows = (mi_params->mi_rows + 2) >> 2;
103
13.3k
  mi_params->MBs = mi_params->mb_rows * mi_params->mb_cols;
104
105
13.3k
  mi_params->mi_alloc_bsize = BLOCK_4X4;
106
13.3k
  mi_params->mi_alloc_stride = mi_params->mi_stride;
107
108
13.3k
  assert(mi_size_wide[mi_params->mi_alloc_bsize] ==
109
13.3k
         mi_size_high[mi_params->mi_alloc_bsize]);
110
13.3k
}
111
112
27.8k
static void dec_setup_mi(CommonModeInfoParams *mi_params) {
113
27.8k
  const int mi_grid_size =
114
27.8k
      mi_params->mi_stride * calc_mi_size(mi_params->mi_rows);
115
27.8k
  memset(mi_params->mi_grid_base, 0,
116
27.8k
         mi_grid_size * sizeof(*mi_params->mi_grid_base));
117
27.8k
  memset(mi_params->submi_grid_base, 0,
118
27.8k
         mi_grid_size * sizeof(*mi_params->submi_grid_base));
119
27.8k
  memset(mi_params->cctx_type_map, 0,
120
27.8k
         mi_grid_size * sizeof(*mi_params->cctx_type_map));
121
27.8k
  av2_reset_txk_skip_array_using_mi_params(mi_params);
122
27.8k
}
123
124
29.9k
static void dec_free_mi(CommonModeInfoParams *mi_params) {
125
29.9k
  avm_free(mi_params->mi_alloc);
126
29.9k
  mi_params->mi_alloc = NULL;
127
29.9k
  avm_free(mi_params->mi_grid_base);
128
29.9k
  mi_params->mi_grid_base = NULL;
129
29.9k
  avm_free(mi_params->mi_alloc_sub);
130
29.9k
  mi_params->mi_alloc_sub = NULL;
131
29.9k
  avm_free(mi_params->submi_grid_base);
132
29.9k
  mi_params->submi_grid_base = NULL;
133
29.9k
  mi_params->mi_alloc_size = 0;
134
29.9k
  avm_free(mi_params->tx_type_map);
135
29.9k
  mi_params->tx_type_map = NULL;
136
29.9k
  avm_free(mi_params->cctx_type_map);
137
29.9k
  mi_params->cctx_type_map = NULL;
138
29.9k
  av2_dealloc_class_id_array(mi_params);
139
29.9k
  av2_dealloc_txk_skip_array(mi_params);
140
29.9k
}
141
142
16.7k
static INLINE void dec_init_tip_ref_frame(AV2_COMMON *const cm) {
143
16.7k
  TIP *tip_ref = &cm->tip_ref;
144
16.7k
  tip_ref->tip_frame = avm_calloc(1, sizeof(*tip_ref->tip_frame));
145
16.7k
  tip_ref->tmp_tip_frame = avm_calloc(1, sizeof(*tip_ref->tmp_tip_frame));
146
16.7k
}
147
148
16.7k
static INLINE void dec_free_tip_ref_frame(AV2_COMMON *const cm) {
149
16.7k
  avm_free_frame_buffer(&cm->tip_ref.tip_frame->buf);
150
16.7k
  avm_free(cm->tip_ref.tip_frame);
151
16.7k
  cm->tip_ref.tip_frame = NULL;
152
153
16.7k
  avm_free_frame_buffer(&cm->tip_ref.tmp_tip_frame->buf);
154
16.7k
  avm_free(cm->tip_ref.tmp_tip_frame);
155
16.7k
  cm->tip_ref.tmp_tip_frame = NULL;
156
16.7k
}
157
158
#if CONFIG_PARAKIT_COLLECT_DATA
159
AV2Decoder *av2_decoder_create(BufferPool *const pool, const char *path,
160
                               const char *suffix) {
161
#else
162
16.7k
AV2Decoder *av2_decoder_create(BufferPool *const pool) {
163
16.7k
#endif
164
16.7k
  AV2Decoder *volatile const pbi = avm_memalign(32, sizeof(*pbi));
165
16.7k
  if (!pbi) return NULL;
166
16.7k
  av2_zero(*pbi);
167
168
16.7k
  AV2_COMMON *volatile const cm = &pbi->common;
169
170
  // The jmp_buf is valid only for the duration of the function that calls
171
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
172
  // before it returns.
173
16.7k
  if (setjmp(cm->error.jmp)) {
174
0
    cm->error.setjmp = 0;
175
0
    av2_decoder_remove(pbi);
176
0
    return NULL;
177
0
  }
178
179
16.7k
  cm->error.setjmp = 1;
180
181
16.7k
  CHECK_MEM_ERROR(cm, cm->fc,
182
16.7k
                  (FRAME_CONTEXT *)avm_memalign(32, sizeof(*cm->fc)));
183
16.7k
  CHECK_MEM_ERROR(
184
16.7k
      cm, cm->default_frame_context,
185
16.7k
      (FRAME_CONTEXT *)avm_memalign(32, sizeof(*cm->default_frame_context)));
186
16.7k
  memset(cm->fc, 0, sizeof(*cm->fc));
187
16.7k
  memset(cm->default_frame_context, 0, sizeof(*cm->default_frame_context));
188
189
16.7k
  pbi->need_resync = 1;
190
16.7k
  avm_once(initialize_dec);
191
192
  // Initialize the references to not point to any frame buffers.
193
284k
  for (int i = 0; i < NELEMENTS(cm->ref_frame_map); i++) {
194
268k
    cm->ref_frame_map[i] = NULL;
195
268k
  }
196
197
16.7k
  cm->current_frame.frame_number = 0;
198
16.7k
  pbi->decoding_first_frame = 1;
199
16.7k
  pbi->common.buffer_pool = pool;
200
201
16.7k
  cm->seq_params.bit_depth = AVM_BITS_8;
202
16.7k
  cm->mi_params.free_mi = dec_free_mi;
203
16.7k
  cm->mi_params.setup_mi = dec_setup_mi;
204
16.7k
  cm->mi_params.set_mb_mi = dec_set_mb_mi;
205
206
16.7k
  cm->frame_filter_dictionary_stride = 0;
207
16.7k
  cm->frame_filter_dictionary = NULL;
208
16.7k
  cm->translated_pcwiener_filters = NULL;
209
16.7k
  cm->num_ref_filters = NULL;
210
211
16.7k
  av2_loop_filter_init(cm);
212
268k
  for (int i = 0; i < NUM_CUSTOM_QMS; ++i) {
213
251k
    pbi->qm_protected[i] = 0;
214
251k
  }
215
216
268k
  for (int i = 0; i < NUM_CUSTOM_QMS; ++i) {
217
251k
    pbi->qm_list[i].qm_from_leading = 0;
218
251k
    pbi->qm_list[i].qm_id = -1;
219
251k
    pbi->qm_list[i].qm_tlayer_id = -1;
220
251k
    pbi->qm_list[i].qm_mlayer_id = -1;
221
251k
    pbi->qm_list[i].quantizer_matrix = NULL;
222
251k
    pbi->qm_list[i].quantizer_matrix_allocated = false;
223
251k
    pbi->qm_list[i].quantizer_matrix_num_planes = -1;
224
251k
  }
225
150k
  for (int i = 0; i < MAX_FGM_NUM; ++i) {
226
134k
    pbi->fgm_list[i].fgm_from_leading = 0;
227
134k
    pbi->fgm_list[i].fgm_id = -1;
228
134k
    pbi->fgm_list[i].fgm_tlayer_id = -1;
229
134k
    pbi->fgm_list[i].fgm_mlayer_id = -1;
230
134k
  }
231
232
16.7k
  pbi->selected_ops_id = -1;
233
16.7k
  pbi->selected_op_index = -1;
234
235
16.7k
  memset(&pbi->last_frame_unit, -1, sizeof(pbi->last_frame_unit));
236
16.7k
  memset(&pbi->last_displayable_frame_unit, -1,
237
16.7k
         sizeof(pbi->last_displayable_frame_unit));
238
16.7k
  memset(pbi->last_output_doh, -1, sizeof(pbi->last_output_doh));
239
16.7k
  pbi->this_is_first_vcl_obu_in_tu = 0;
240
16.7k
  pbi->last_decoded_xlayer_id = -1;
241
150k
  for (int i = 0; i < MAX_NUM_MLAYERS; i++) {
242
134k
    pbi->num_displayable_frame_unit[i] = 0;
243
134k
  }
244
83.7k
  for (int j = 0; j < MAX_NUM_TLAYERS; j++)
245
603k
    for (int i = 0; i < MAX_NUM_MLAYERS; i++)
246
536k
      memset(pbi->obus_in_frame_unit_data[j][i], 0,
247
536k
             sizeof(pbi->obus_in_frame_unit_data[j][i]));
248
249
553k
  for (int xlayer = 0; xlayer < MAX_NUM_XLAYERS; xlayer++)
250
9.11M
    for (int i = 0; i < MAX_SEQ_NUM; i++)
251
8.58M
      pbi->seq_list[xlayer][i].seq_header_id = -1;
252
253
#if CONFIG_ACCOUNTING
254
  pbi->acct_enabled = 1;
255
  avm_accounting_init(&pbi->accounting);
256
#endif
257
258
16.7k
  dec_init_tip_ref_frame(cm);
259
260
16.7k
  cm->error.setjmp = 0;
261
262
16.7k
  avm_get_worker_interface()->init(&pbi->lf_worker);
263
16.7k
  pbi->lf_worker.thread_name = "avm lf worker";
264
265
  // Initialize the Content Interpretation parameters
266
150k
  for (int i = 0; i < MAX_NUM_MLAYERS; i++) {
267
134k
    av2_initialize_ci_params(&cm->ci_params_per_layer[i]);
268
134k
  }
269
270
#if CONFIG_PARAKIT_COLLECT_DATA
271
#include "av2/common/entropy_inits_coeffs.h"
272
#include "av2/common/entropy_inits_modes.h"
273
#include "av2/common/entropy_inits_mv.h"
274
275
  // @ParaKit: add side information needed in array of prob_models structure to
276
  // be used in collecting data
277
  cm->prob_models[EOB_FLAG_CDF16] =
278
      (ProbModelInfo){ .ctx_group_name = "eob_flag_cdf16",
279
                       .prob = (avm_cdf_prob *)av2_default_eob_multi16_cdfs,
280
                       .cdf_stride = 0,
281
                       .num_symb = 5,
282
                       .num_dim = 2,
283
                       .num_idx = { 0, 0, 4, 3 } };
284
  cm->prob_models[EOB_FLAG_CDF32] =
285
      (ProbModelInfo){ .ctx_group_name = "eob_flag_cdf32",
286
                       .prob = (avm_cdf_prob *)av2_default_eob_multi32_cdfs,
287
                       .cdf_stride = 0,
288
                       .num_symb = 6,
289
                       .num_dim = 2,
290
                       .num_idx = { 0, 0, 4, 3 } };
291
292
  for (int i = 0; i < MAX_NUM_CTX_GROUPS; i++) {
293
    for (int j = 0; j < MAX_DIMS_CONTEXT3; j++)
294
      for (int k = 0; k < MAX_DIMS_CONTEXT2; k++)
295
        for (int l = 0; l < MAX_DIMS_CONTEXT1; l++)
296
          for (int h = 0; h < MAX_DIMS_CONTEXT0; h++)
297
            beginningFrameFlag[i][j][k][l][h] = 0;
298
  }
299
300
  for (int f = 0; f < MAX_NUM_CTX_GROUPS; f++) {
301
    cm->prob_models[f].model_idx = f;
302
    const int fixed_stride = cm->prob_models[f].cdf_stride;
303
    const int num_sym = cm->prob_models[f].num_symb;
304
    const int num_dims = cm->prob_models[f].num_dim;
305
    const int num_idx0 = cm->prob_models[f].num_idx[0];
306
    const int num_idx1 = cm->prob_models[f].num_idx[1];
307
    const int num_idx2 = cm->prob_models[f].num_idx[2];
308
    const int num_idx3 = cm->prob_models[f].num_idx[3];
309
    const char *str_ctx = cm->prob_models[f].ctx_group_name;
310
    const char *str_path = path ? path : ".";
311
    const char *str_suffix = suffix ? suffix : "data";
312
    char filename[2048];
313
    sprintf(filename, "%s/Stat_%s_%s.csv", str_path, str_ctx, str_suffix);
314
    FILE *fData = fopen(filename, "wt");
315
    cm->prob_models[f].fDataCollect = fData;
316
317
    fprintf(fData, "Header:%s,%d,%d", str_ctx, num_sym, num_dims);
318
    const int dim_offset = MAX_CTX_DIM - num_dims;
319
    for (int i = 0; i < num_dims; i++) {
320
      fprintf(fData, ",%d", cm->prob_models[f].num_idx[i + dim_offset]);
321
    }
322
    fprintf(fData, "\n");
323
324
    avm_cdf_prob *prob_ptr;
325
    prob_ptr = cm->prob_models[f].prob;
326
    int ctx_group_counter = 0;
327
    for (int d0 = 0; d0 < (num_idx0 == 0 ? 1 : num_idx0); d0++)
328
      for (int d1 = 0; d1 < (num_idx1 == 0 ? 1 : num_idx1); d1++)
329
        for (int d2 = 0; d2 < (num_idx2 == 0 ? 1 : num_idx2); d2++)
330
          for (int d3 = 0; d3 < (num_idx3 == 0 ? 1 : num_idx3); d3++) {
331
            // indexing according to MAX_CTX_DIM
332
            fprintf(fData, "%d,%d,%d,%d,%d,", ctx_group_counter, d0, d1, d2,
333
                    d3);
334
            ctx_group_counter++;
335
            for (int sym = 0; sym < CDF_SIZE(num_sym); sym++) {
336
              int cdf_stride = (fixed_stride == 0) ? num_sym : fixed_stride;
337
              int offset =
338
                  (d0 * num_idx3 * num_idx2 * num_idx1 * CDF_SIZE(cdf_stride)) +
339
                  (d1 * num_idx3 * num_idx2 * CDF_SIZE(cdf_stride)) +
340
                  (d2 * num_idx3 * CDF_SIZE(cdf_stride)) +
341
                  (d3 * CDF_SIZE(cdf_stride)) + sym;
342
              if (sym < num_sym)
343
                fprintf(fData, "%d", (int)AVM_ICDF(*(prob_ptr + offset)));
344
              else
345
                fprintf(fData, "%d", (int)*(prob_ptr + offset));
346
              if (sym < CDF_SIZE(num_sym - 1)) {
347
                fprintf(fData, ",");
348
              } else {
349
                fprintf(fData, "\n");
350
              }
351
            }
352
          }
353
    // main header
354
    for (int i = 0; i < num_dims; i++) {
355
      fprintf(fData, "Dim%d,", i);
356
    }
357
358
    fprintf(fData, "FrameNum,FrameType,isBeginFrame,Counter,Value,Cost");
359
360
    for (int sym = 0; sym < num_sym; sym++) {
361
      fprintf(fData, ",cdf%d", sym);
362
    }
363
    fprintf(fData, ",rate");
364
    fprintf(fData, "\n");
365
  }
366
#endif
367
16.7k
  return pbi;
368
16.7k
}
369
370
9.76k
void av2_dealloc_dec_jobs(struct AV2DecTileMTData *tile_mt_info) {
371
9.76k
  if (tile_mt_info != NULL) {
372
9.76k
#if CONFIG_MULTITHREAD
373
9.76k
    if (tile_mt_info->job_mutex != NULL) {
374
4.80k
      pthread_mutex_destroy(tile_mt_info->job_mutex);
375
4.80k
      avm_free(tile_mt_info->job_mutex);
376
4.80k
    }
377
9.76k
#endif
378
9.76k
    avm_free(tile_mt_info->job_queue);
379
    // clear the structure as the source of this call may be a resize in which
380
    // case this call will be followed by an _alloc() which may fail.
381
9.76k
    av2_zero(*tile_mt_info);
382
9.76k
  }
383
9.76k
}
384
385
16.7k
void av2_dec_free_cb_buf(AV2Decoder *pbi) {
386
16.7k
  avm_free(pbi->cb_buffer_base);
387
16.7k
  pbi->cb_buffer_base = NULL;
388
16.7k
  pbi->cb_buffer_alloc_size = 0;
389
16.7k
}
390
391
16.7k
void av2_decoder_remove(AV2Decoder *pbi) {
392
16.7k
  int i;
393
394
16.7k
  if (!pbi) return;
395
396
16.7k
  avm_get_worker_interface()->end(&pbi->lf_worker);
397
16.7k
  avm_free(pbi->lf_worker.data1);
398
399
16.7k
  if (pbi->thread_data) {
400
166k
    for (int worker_idx = 0; worker_idx < pbi->max_threads - 1; worker_idx++) {
401
161k
      DecWorkerData *const thread_data = pbi->thread_data + worker_idx;
402
161k
      av2_free_mc_tmp_buf(thread_data->td);
403
161k
      av2_free_opfl_tmp_bufs(thread_data->td);
404
161k
      avm_free(thread_data->td);
405
161k
    }
406
4.95k
    avm_free(pbi->thread_data);
407
4.95k
  }
408
409
183k
  for (i = 0; i < pbi->num_workers; ++i) {
410
166k
    AVxWorker *const worker = &pbi->tile_workers[i];
411
166k
    avm_get_worker_interface()->end(worker);
412
166k
  }
413
16.7k
#if CONFIG_MULTITHREAD
414
16.7k
  if (pbi->row_mt_mutex_ != NULL) {
415
0
    pthread_mutex_destroy(pbi->row_mt_mutex_);
416
0
    avm_free(pbi->row_mt_mutex_);
417
0
  }
418
16.7k
  if (pbi->row_mt_cond_ != NULL) {
419
0
    pthread_cond_destroy(pbi->row_mt_cond_);
420
0
    avm_free(pbi->row_mt_cond_);
421
0
  }
422
16.7k
#endif
423
83.6k
  for (i = 0; i < pbi->allocated_tiles; i++) {
424
66.8k
    TileDataDec *const tile_data = pbi->tile_data + i;
425
66.8k
    av2_dec_row_mt_dealloc(&tile_data->dec_row_mt_sync);
426
66.8k
  }
427
16.7k
  avm_free(pbi->tile_data);
428
16.7k
  avm_free(pbi->tile_workers);
429
430
16.7k
  if (pbi->num_workers > 0) {
431
4.95k
    av2_loop_filter_dealloc(&pbi->lf_row_sync);
432
4.95k
    av2_ccso_filter_dealloc(&pbi->ccso_sync);
433
4.95k
    av2_loop_restoration_dealloc(&pbi->lr_row_sync, pbi->num_workers);
434
4.95k
    av2_dealloc_dec_jobs(&pbi->tile_mt_info);
435
4.95k
    avm_free(pbi->tip_worker_data);
436
4.95k
    av2_tip_dealloc(&pbi->tip_sync);
437
4.95k
  }
438
439
16.7k
  dec_free_tip_ref_frame(&pbi->common);
440
441
16.7k
  free_bru_info(&pbi->common);
442
16.7k
  av2_dec_free_cb_buf(pbi);
443
#if CONFIG_ACCOUNTING
444
  avm_accounting_clear(&pbi->accounting);
445
#endif
446
16.7k
  av2_free_mc_tmp_buf(&pbi->td);
447
16.7k
  av2_free_opfl_tmp_bufs(&pbi->td);
448
16.7k
  avm_img_metadata_array_free(pbi->metadata);
449
450
#if CONFIG_PARAKIT_COLLECT_DATA
451
  for (int f = 0; f < MAX_NUM_CTX_GROUPS; f++) {
452
    if (pbi->common.prob_models[f].fDataCollect != NULL) {
453
      fclose(pbi->common.prob_models[f].fDataCollect);
454
    }
455
  }
456
#endif
457
268k
  for (int qm_pos = 0; qm_pos < NUM_CUSTOM_QMS; qm_pos++) {
458
251k
    if (pbi->qm_list[qm_pos].quantizer_matrix != NULL)
459
279
      av2_free_qmset(pbi->qm_list[qm_pos].quantizer_matrix);
460
251k
  }
461
462
16.7k
  if (pbi->is_multistream) {
463
    // Release intermediate buffers to store internal variables per sub-stream
464
263
    if (pbi->stream_info != NULL) {
465
182
      avm_free(pbi->stream_info);
466
182
      pbi->stream_info = NULL;
467
182
      pbi->glcr_stream_info_num_allocated = 0;
468
182
    }
469
263
  }
470
471
16.7k
  avm_free(pbi);
472
16.7k
}
473
474
void av2_visit_palette(AV2Decoder *const pbi, MACROBLOCKD *const xd,
475
3.94M
                       avm_reader *r, palette_visitor_fn_t visit) {
476
3.94M
  if (!is_inter_block(xd->mi[0], xd->tree_type)) {
477
3.78M
    const int plane_start = get_partition_plane_start(xd->tree_type);
478
3.78M
    const int plane_end = get_partition_plane_end(
479
3.78M
        xd->tree_type, AVMMIN(2, av2_num_planes(&pbi->common)));
480
9.18M
    for (int plane = plane_start; plane < plane_end; ++plane) {
481
5.40M
      if (plane == 0 || xd->is_chroma_ref) {
482
5.30M
        if (xd->mi[0]->palette_mode_info.palette_size[plane])
483
60.5k
          visit(xd, plane, r);
484
5.30M
      } else {
485
100k
        assert(xd->mi[0]->palette_mode_info.palette_size[plane] == 0);
486
100k
      }
487
5.40M
    }
488
3.78M
  }
489
3.94M
}
490
491
static int equal_dimensions(const YV12_BUFFER_CONFIG *a,
492
0
                            const YV12_BUFFER_CONFIG *b) {
493
0
  return a->y_height == b->y_height && a->y_width == b->y_width &&
494
0
         a->uv_height == b->uv_height && a->uv_width == b->uv_width;
495
0
}
496
497
avm_codec_err_t av2_copy_reference_dec(AV2Decoder *pbi, int idx,
498
0
                                       YV12_BUFFER_CONFIG *sd) {
499
0
  AV2_COMMON *cm = &pbi->common;
500
0
  const int num_planes = av2_num_planes(cm);
501
  // Ensure that avm_internal_error() calls longjmp().
502
0
  assert(cm->error.setjmp);
503
504
0
  const YV12_BUFFER_CONFIG *const cfg = get_ref_frame(cm, idx);
505
0
  if (cfg == NULL) {
506
0
    avm_internal_error(&cm->error, AVM_CODEC_ERROR, "No reference frame");
507
0
  }
508
0
  if (!equal_dimensions(cfg, sd))
509
0
    avm_internal_error(&cm->error, AVM_CODEC_ERROR,
510
0
                       "Incorrect buffer dimensions");
511
0
  else
512
0
    avm_yv12_copy_frame(cfg, sd, num_planes);
513
514
0
  return cm->error.error_code;
515
0
}
516
517
avm_codec_err_t av2_set_reference_dec(AV2_COMMON *cm, int idx,
518
                                      int use_external_ref,
519
0
                                      YV12_BUFFER_CONFIG *sd) {
520
0
  const int num_planes = av2_num_planes(cm);
521
0
  YV12_BUFFER_CONFIG *ref_buf = NULL;
522
  // Ensure that avm_internal_error() calls longjmp().
523
0
  assert(cm->error.setjmp);
524
  // Get the destination reference buffer.
525
0
  ref_buf = get_ref_frame(cm, idx);
526
527
0
  if (ref_buf == NULL) {
528
0
    avm_internal_error(&cm->error, AVM_CODEC_ERROR, "No reference frame");
529
0
  }
530
531
0
  if (!use_external_ref) {
532
0
    if (!equal_dimensions(ref_buf, sd)) {
533
0
      avm_internal_error(&cm->error, AVM_CODEC_ERROR,
534
0
                         "Incorrect buffer dimensions");
535
0
    } else {
536
      // Overwrite the reference frame buffer.
537
0
      avm_yv12_copy_frame(sd, ref_buf, num_planes);
538
0
    }
539
0
  } else {
540
0
    if (!avm_equal_dimensions_and_border(ref_buf, sd)) {
541
0
      avm_internal_error(&cm->error, AVM_CODEC_ERROR,
542
0
                         "Incorrect buffer dimensions");
543
0
    } else {
544
      // Overwrite the reference frame buffer pointers.
545
      // Once we no longer need the external reference buffer, these pointers
546
      // are restored.
547
0
      ref_buf->store_buf_adr[0] = ref_buf->y_buffer;
548
0
      ref_buf->store_buf_adr[1] = ref_buf->u_buffer;
549
0
      ref_buf->store_buf_adr[2] = ref_buf->v_buffer;
550
0
      ref_buf->y_buffer = sd->y_buffer;
551
0
      ref_buf->u_buffer = sd->u_buffer;
552
0
      ref_buf->v_buffer = sd->v_buffer;
553
0
      ref_buf->use_external_reference_buffers = 1;
554
0
    }
555
0
  }
556
557
0
  return cm->error.error_code;
558
0
}
559
560
avm_codec_err_t av2_copy_new_frame_dec(AV2_COMMON *cm,
561
                                       YV12_BUFFER_CONFIG *new_frame,
562
0
                                       YV12_BUFFER_CONFIG *sd) {
563
0
  const int num_planes = av2_num_planes(cm);
564
565
0
  if (!avm_equal_dimensions_and_border(new_frame, sd))
566
0
    avm_internal_error(&cm->error, AVM_CODEC_ERROR,
567
0
                       "Incorrect buffer dimensions");
568
0
  else
569
0
    avm_yv12_copy_frame(new_frame, sd, num_planes);
570
571
0
  return cm->error.error_code;
572
0
}
573
574
30.5k
static void release_current_frame(AV2Decoder *pbi) {
575
30.5k
  AV2_COMMON *const cm = &pbi->common;
576
30.5k
  BufferPool *const pool = cm->buffer_pool;
577
578
30.5k
  cm->cur_frame->buf.corrupted = 1;
579
30.5k
  lock_buffer_pool(pool);
580
30.5k
  decrease_ref_count(cm->cur_frame, pool);
581
30.5k
  unlock_buffer_pool(pool);
582
30.5k
  cm->cur_frame = NULL;
583
30.5k
}
584
585
// This function flushes out the DPB, all the slots in the dpb is free to use.
586
avm_codec_err_t flush_remaining_frames(struct AV2Decoder *pbi,
587
13.9k
                                       int order_hint_limit) {
588
13.9k
  avm_codec_err_t res = AVM_CODEC_OK;
589
13.9k
  AV2_COMMON *const cm = &pbi->common;
590
13.9k
  RefCntBuffer *output_candidate = NULL;
591
13.9k
  do {
592
13.9k
    output_candidate = NULL;
593
237k
    for (int i = 0; i < REF_FRAMES; i++) {
594
223k
      RefCntBuffer *const buf = cm->ref_frame_map[i];
595
223k
      if (buf == NULL) continue;
596
0
      if (!is_frame_eligible_for_output(buf)) continue;
597
0
      if ((int)buf->display_order_hint >= order_hint_limit) continue;
598
599
0
      if ((output_candidate == NULL ||
600
0
           derive_output_order_idx(cm, buf) <=
601
0
               derive_output_order_idx(cm, output_candidate))) {
602
0
        output_candidate = buf;
603
0
      }
604
0
    }
605
13.9k
    if (output_candidate != NULL) {
606
0
      if (pbi->num_output_frames >= (REF_FRAMES + 1) * AVM_MAX_NUM_STREAMS) {
607
0
        return AVM_CODEC_MEM_ERROR;
608
0
      }
609
0
      assign_output_frame_buffer_p(
610
0
          &pbi->output_frames[pbi->num_output_frames++], output_candidate);
611
0
      output_candidate->frame_output_done = 1;
612
0
    }
613
13.9k
  } while (output_candidate != NULL);
614
13.9k
  return res;
615
13.9k
}
616
617
// check uniqueness and ascending order at output time, then update
618
// last_output_doh.  Returns 0 on success, 1 on violation.
619
static int check_and_update_output_doh(AV2Decoder *pbi,
620
10
                                       const RefCntBuffer *frame) {
621
10
  const int xl = frame->xlayer_id;
622
10
  const int ml = frame->mlayer_id;
623
10
  const int doh = frame->display_order_hint;
624
625
10
  const int last_doh = pbi->last_output_doh[xl][ml];
626
10
  if (doh <= last_doh) return 1;
627
628
10
  pbi->last_output_doh[xl][ml] = doh;
629
10
  return 0;
630
10
}
631
632
448
int av2_output_frame_buffers(AV2Decoder *pbi, int ref_idx) {
633
448
  AV2_COMMON *const cm = &pbi->common;
634
448
  RefCntBuffer *trigger_frame = NULL;
635
448
  RefCntBuffer *output_candidate = NULL;
636
448
  int doh_error = 0;
637
638
  // Determine if the triggering frame is the current frame or a frame
639
  // already stored in the refrence buffer.
640
448
  trigger_frame = (ref_idx >= 0) ? cm->ref_frame_map[ref_idx] : cm->cur_frame;
641
642
  // Add the previous frames into the output queue.
643
448
  do {
644
448
    output_candidate = trigger_frame;
645
1.62k
    for (int i = 0; i < cm->seq_params.ref_frames; i++) {
646
1.17k
      if (is_frame_eligible_for_output(cm->ref_frame_map[i]) &&
647
0
          derive_output_order_idx(cm, cm->ref_frame_map[i]) <
648
0
              derive_output_order_idx(cm, output_candidate)) {
649
0
        output_candidate = cm->ref_frame_map[i];
650
0
      }
651
1.17k
    }
652
448
    if (output_candidate != trigger_frame) {
653
0
      if (cm->seq_params.monotonic_output_order_flag == 0) {
654
0
        doh_error |= check_and_update_output_doh(pbi, output_candidate);
655
0
      }
656
0
      assign_output_frame_buffer_p(
657
0
          &pbi->output_frames[pbi->num_output_frames++], output_candidate);
658
0
      output_candidate->frame_output_done = 1;
659
#if CONFIG_BITSTREAM_DEBUG
660
      avm_bitstream_queue_set_frame_read(
661
          derive_output_order_idx(cm, output_candidate) * 2 + 1);
662
#endif  // CONFIG_BITSTREAM_DEBUG
663
#if CONFIG_MISMATCH_DEBUG
664
      mismatch_move_frame_idx_r(0);
665
#endif  // CONFIG_MISMATCH_DEBUG
666
0
    }
667
448
  } while (output_candidate != trigger_frame);
668
669
448
  if (cm->seq_params.monotonic_output_order_flag == 0) {
670
    // Add the output triggering frame into the output queue.
671
10
    doh_error |= check_and_update_output_doh(pbi, trigger_frame);
672
10
  }
673
448
  assign_output_frame_buffer_p(&pbi->output_frames[pbi->num_output_frames++],
674
448
                               trigger_frame);
675
448
  trigger_frame->frame_output_done = 1;
676
677
#if CONFIG_BITSTREAM_DEBUG
678
  if (trigger_frame->order_hint != cm->cur_frame->order_hint) {
679
    avm_bitstream_queue_set_frame_read(
680
        derive_output_order_idx(cm, trigger_frame) * 2 + 1);
681
  }
682
#endif  // CONFIG_BITSTREAM_DEBUG
683
#if CONFIG_MISMATCH_DEBUG
684
  if (trigger_frame->display_order_hint != cm->cur_frame->display_order_hint)
685
    mismatch_move_frame_idx_r(0);
686
#endif  // CONFIG_MISMATCH_DEBUG
687
688
  // Add the next frames (implicit_output_picture == 1) into the output queue.
689
448
  uint64_t trigger_frame_output_order =
690
448
      derive_output_order_idx(cm, trigger_frame);
691
692
448
  int successive_output = 1;
693
896
  for (int k = 1; k <= cm->seq_params.ref_frames && successive_output > 0;
694
448
       k++) {
695
448
    uint64_t next_frame_output_order = trigger_frame_output_order + k;
696
448
    successive_output = 0;
697
1.62k
    for (int i = 0; i < cm->seq_params.ref_frames; i++) {
698
1.17k
      if (is_frame_eligible_for_output(cm->ref_frame_map[i]) &&
699
0
          derive_output_order_idx(cm, cm->ref_frame_map[i]) ==
700
0
              next_frame_output_order) {
701
0
        if (cm->seq_params.monotonic_output_order_flag == 0) {
702
0
          doh_error |= check_and_update_output_doh(pbi, cm->ref_frame_map[i]);
703
0
        }
704
0
        assign_output_frame_buffer_p(
705
0
            &pbi->output_frames[pbi->num_output_frames++],
706
0
            cm->ref_frame_map[i]);
707
0
        cm->ref_frame_map[i]->frame_output_done = 1;
708
0
        successive_output++;
709
#if CONFIG_BITSTREAM_DEBUG
710
        avm_bitstream_queue_set_frame_read(
711
            derive_output_order_idx(cm, cm->ref_frame_map[i]) * 2 + 1);
712
#endif  // CONFIG_BITSTREAM_DEBUG
713
#if CONFIG_MISMATCH_DEBUG
714
        mismatch_move_frame_idx_r(0);
715
#endif  // CONFIG_MISMATCH_DEBUG
716
0
      }
717
1.17k
    }
718
448
  }
719
448
  return doh_error;
720
448
}
721
722
// If any buffer updating is signaled it should be done here.
723
// Consumes a reference to cm->cur_frame.
724
//
725
// This functions returns void. It reports failure by setting
726
// cm->error.error_code.
727
463
static void update_frame_buffers(AV2Decoder *pbi, int frame_decoded) {
728
463
  int ref_index = 0;
729
463
  AV2_COMMON *const cm = &pbi->common;
730
463
  BufferPool *const pool = cm->buffer_pool;
731
463
  int doh_error = 0;
732
733
463
  pbi->output_frames_offset = 0;
734
735
463
  if (frame_decoded) {
736
463
    lock_buffer_pool(pool);
737
738
    // Don't clear is_restricted for bridge frames - they should maintain
739
    // the restricted status inherited from their reference frame
740
463
    if (!cm->bridge_frame_info.is_bridge_frame) {
741
463
      cm->cur_frame->is_restricted = false;
742
463
    }
743
744
463
    int first_ref_index;
745
463
    const bool clear_multiple_insert_in_one =
746
463
        av2_frame_clears_multiple_inserted_in_one(
747
463
            cm->current_frame.refresh_frame_flags, cm->current_frame.frame_type,
748
463
            &first_ref_index);
749
750
    // The following for loop needs to release the reference stored in
751
    // cm->ref_frame_map[ref_index] before storing a reference to
752
    // cm->cur_frame in cm->ref_frame_map[ref_index].
753
1.65k
    for (int mask = cm->current_frame.refresh_frame_flags; mask; mask >>= 1) {
754
1.19k
      if (mask & 1) {
755
1.04k
        if (pbi->bru_opt_mode && cm->bru.enabled) {
756
0
          if (ref_index == cm->bru.explicit_ref_idx) {
757
0
            ++ref_index;
758
0
            continue;  // skip refresh BRU ref
759
0
          }
760
0
        }
761
1.04k
        if (is_frame_eligible_for_output(cm->ref_frame_map[ref_index]))
762
0
          doh_error |= av2_output_frame_buffers(pbi, ref_index);
763
1.04k
        decrease_ref_count(cm->ref_frame_map[ref_index], pool);
764
765
1.04k
        if (av2_skip_reference_buffer_update(clear_multiple_insert_in_one,
766
1.04k
                                             ref_index, first_ref_index)) {
767
586
          cm->ref_frame_map[ref_index] = NULL;
768
586
        } else {
769
461
          cm->ref_frame_map[ref_index] = cm->cur_frame;
770
461
          ++cm->cur_frame->ref_count;
771
461
        }
772
1.04k
      }
773
1.19k
      ++ref_index;
774
1.19k
    }
775
463
    update_subgop_stats(cm, &pbi->subgop_stats, cm->cur_frame->order_hint,
776
463
                        pbi->enable_subgop_stats);
777
463
    if (((cm->immediate_output_picture && !cm->cur_frame->frame_output_done) ||
778
448
         cm->show_existing_frame)) {
779
448
      doh_error |= av2_output_frame_buffers(pbi, -1);
780
448
      decrease_ref_count(cm->cur_frame, pool);
781
448
    } else {
782
15
      decrease_ref_count(cm->cur_frame, pool);
783
15
    }
784
463
    unlock_buffer_pool(pool);
785
463
    if (cm->seq_params.monotonic_output_order_flag == 0) {
786
18
      if (doh_error) {
787
0
        avm_internal_error(
788
0
            &cm->error, AVM_CODEC_UNSUP_BITSTREAM,
789
0
            "Display order hint of an output picture is not unique"
790
0
            " in the same (xlayer_id %d) layer.",
791
0
            cm->xlayer_id);
792
0
      }
793
18
    }
794
463
  } else {
795
    // Nothing was decoded, so just drop this frame buffer
796
0
    lock_buffer_pool(pool);
797
0
    decrease_ref_count(cm->cur_frame, pool);
798
0
    unlock_buffer_pool(pool);
799
0
  }
800
463
  cm->cur_frame = NULL;
801
802
  // Invalidate these references until the next frame starts.
803
3.70k
  for (ref_index = 0; ref_index < INTER_REFS_PER_FRAME; ref_index++) {
804
3.24k
    cm->remapped_ref_idx[ref_index] = INVALID_IDX;
805
3.24k
  }
806
463
}
807
808
int av2_receive_compressed_data(AV2Decoder *pbi, size_t size,
809
30.9k
                                const uint8_t **psource) {
810
30.9k
  AV2_COMMON *volatile const cm = &pbi->common;
811
30.9k
  const uint8_t *source = *psource;
812
30.9k
  cm->error.error_code = AVM_CODEC_OK;
813
30.9k
  cm->error.has_detail = 0;
814
30.9k
  cm->decoding = 1;
815
816
30.9k
  if (size == 0) {
817
    // This is used to signal that we are missing frames.
818
    // We do not know if the missing frame(s) was supposed to update
819
    // any of the reference buffers, but we act conservative and
820
    // mark only the last buffer as corrupted.
821
    //
822
    // TODO(jkoleszar): Error concealment is undefined and non-normative
823
    // at this point, but if it becomes so, [0] may not always be the correct
824
    // thing to do here.
825
0
    const int last_frame = get_closest_pastcur_ref_or_ref0(cm);
826
0
    RefCntBuffer *ref_buf = get_ref_frame_buf(cm, last_frame);
827
0
    if (ref_buf != NULL) ref_buf->buf.corrupted = 1;
828
0
  }
829
30.9k
  check_ref_count_status_dec(pbi);
830
30.9k
  if (assign_cur_frame_new_fb(cm) == NULL) {
831
0
    cm->error.error_code = AVM_CODEC_MEM_ERROR;
832
0
    return 1;
833
0
  }
834
835
  // The jmp_buf is valid only for the duration of the function that calls
836
  // setjmp(). Therefore, this function must reset the 'setjmp' field to 0
837
  // before it returns.
838
30.9k
  if (setjmp(cm->error.jmp)) {
839
28.2k
    const AVxWorkerInterface *const winterface = avm_get_worker_interface();
840
28.2k
    int i;
841
842
28.2k
    cm->error.setjmp = 0;
843
844
    // Synchronize all threads immediately as a subsequent decode call may
845
    // cause a resize invalidating some allocations.
846
28.2k
    winterface->sync(&pbi->lf_worker);
847
262k
    for (i = 0; i < pbi->num_workers; ++i) {
848
234k
      winterface->sync(&pbi->tile_workers[i]);
849
234k
    }
850
851
28.2k
    release_current_frame(pbi);
852
28.2k
    avm_clear_system_state();
853
28.2k
    return -1;
854
28.2k
  }
855
856
2.79k
  cm->error.setjmp = 1;
857
858
2.79k
  int frame_decoded =
859
2.79k
      avm_decode_frame_from_obus(pbi, source, source + size, psource);
860
#if CONFIG_INSPECTION
861
  if (cm->features.tip_frame_mode == TIP_FRAME_AS_OUTPUT) {
862
    if (pbi->inspect_tip_cb != NULL) {
863
      (*pbi->inspect_tip_cb)(pbi, pbi->inspect_ctx);
864
    }
865
  }
866
#endif
867
868
2.79k
  if (frame_decoded < 0) {
869
2.32k
    assert(cm->error.error_code != AVM_CODEC_OK);
870
2.32k
    release_current_frame(pbi);
871
2.32k
    cm->error.setjmp = 0;
872
2.32k
    return 1;
873
2.32k
  }
874
875
#if TXCOEFF_TIMER
876
  cm->cum_txcoeff_timer += cm->txcoeff_timer;
877
  fprintf(stderr,
878
          "txb coeff block number: %d, frame time: %ld, cum time %ld in us\n",
879
          cm->txb_count, cm->txcoeff_timer, cm->cum_txcoeff_timer);
880
  cm->txcoeff_timer = 0;
881
  cm->txb_count = 0;
882
#endif
883
884
  // Note: At this point, this function holds a reference to cm->cur_frame
885
  // in the buffer pool. This reference is consumed by update_frame_buffers().
886
463
  check_ref_count_status_dec(pbi);
887
463
  update_frame_buffers(pbi, frame_decoded);
888
463
  check_ref_count_status_dec(pbi);
889
890
463
  if (frame_decoded) {
891
463
    pbi->decoding_first_frame = 0;
892
463
  }
893
894
463
  if (cm->error.error_code != AVM_CODEC_OK) {
895
0
    cm->error.setjmp = 0;
896
0
    return 1;
897
0
  }
898
899
463
  avm_clear_system_state();
900
463
  if (cm->seg.enabled) {
901
170
    if (cm->prev_frame && (cm->mi_params.mi_rows == cm->prev_frame->mi_rows) &&
902
0
        (cm->mi_params.mi_cols == cm->prev_frame->mi_cols)) {
903
0
      cm->last_frame_seg_map = cm->prev_frame->seg_map;
904
170
    } else {
905
170
      cm->last_frame_seg_map = NULL;
906
170
    }
907
170
  }
908
909
  // Update progress in frame parallel decode.
910
463
  cm->error.setjmp = 0;
911
912
463
  return 0;
913
463
}
914
915
// Get the frame at a particular index in the output queue
916
int av2_get_raw_frame(AV2Decoder *pbi, size_t index, YV12_BUFFER_CONFIG **sd,
917
7.67k
                      avm_film_grain_t **grain_params) {
918
7.67k
  if (index >= pbi->num_output_frames) return -1;
919
361
  *sd = &pbi->output_frames[index]->buf;
920
361
  *grain_params = &pbi->output_frames[index]->film_grain_params;
921
361
  avm_clear_system_state();
922
361
  return 0;
923
7.67k
}
924
925
// Get the highest-spatial-layer output
926
// TODO(rachelbarker): What should this do?
927
0
int av2_get_frame_to_show(AV2Decoder *pbi, YV12_BUFFER_CONFIG *frame) {
928
0
  if (pbi->num_output_frames == 0) return -1;
929
0
  const size_t out_frame_idx = pbi->output_frames_offset;
930
0
  if (pbi->num_output_frames <= out_frame_idx) return -1;
931
0
  *frame = pbi->output_frames[out_frame_idx]->buf;
932
0
  return 0;
933
0
}