/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 | } |