FFmpeg
refs.c
Go to the documentation of this file.
1 /*
2  * VVC reference management
3  *
4  * Copyright (C) 2023 Nuo Mi
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <stdatomic.h>
24 #include <stdbool.h>
25 
26 #include "libavutil/mem.h"
27 #include "libavutil/thread.h"
28 #include "libavutil/refstruct.h"
29 #include "libavcodec/thread.h"
30 #include "libavcodec/decode.h"
31 
32 #include "refs.h"
33 
34 
35 typedef struct FrameProgress {
40  uint8_t has_lock;
41  uint8_t has_cond;
43 
45 {
46  /* frame->frame can be NULL if context init failed */
47  if (!frame->frame || !frame->frame->buf[0])
48  return;
49 
50  frame->flags &= ~flags;
51  if (!(frame->flags & ~VVC_FRAME_FLAG_CORRUPT))
52  frame->flags = 0;
53  if (!frame->flags) {
54  av_frame_unref(frame->frame);
55 
56  if (frame->needs_fg) {
57  av_frame_unref(frame->frame_grain);
58  frame->needs_fg = 0;
59  }
60 
63  av_refstruct_unref(&frame->progress);
64 
65  av_refstruct_unref(&frame->tab_dmvr_mvf);
66 
68  frame->nb_rpl_elems = 0;
69  av_refstruct_unref(&frame->rpl_tab);
70 
71  frame->collocated_ref = NULL;
72  av_refstruct_unref(&frame->hwaccel_picture_private);
73  }
74 }
75 
76 const RefPicList *ff_vvc_get_ref_list(const VVCFrameContext *fc, const VVCFrame *ref, int x0, int y0)
77 {
78  const int x_cb = x0 >> fc->ps.sps->ctb_log2_size_y;
79  const int y_cb = y0 >> fc->ps.sps->ctb_log2_size_y;
80  const int pic_width_cb = fc->ps.pps->ctb_width;
81  const int ctb_addr_rs = y_cb * pic_width_cb + x_cb;
82 
83  return (const RefPicList *)ref->rpl_tab[ctb_addr_rs];
84 }
85 
87 {
88  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
89  ff_vvc_unref_frame(fc, &fc->DPB[i],
91 }
92 
94 {
95  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
96  ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
97 }
98 
99 static void free_progress(AVRefStructOpaque unused, void *obj)
100 {
101  FrameProgress *p = (FrameProgress *)obj;
102 
103  if (p->has_cond)
104  ff_cond_destroy(&p->cond);
105  if (p->has_lock)
106  ff_mutex_destroy(&p->lock);
107 }
108 
110 {
112 
113  if (p) {
114  p->has_lock = !ff_mutex_init(&p->lock, NULL);
115  p->has_cond = !ff_cond_init(&p->cond, NULL);
116  if (!p->has_lock || !p->has_cond)
118  }
119  return p;
120 }
121 
123 {
124  const VVCSPS *sps = fc->ps.sps;
125  const VVCPPS *pps = fc->ps.pps;
126  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
127  int ret;
128  VVCFrame *frame = &fc->DPB[i];
129  VVCWindow *win = &frame->scaling_win;
130  if (frame->frame->buf[0])
131  continue;
132 
133  frame->sps = av_refstruct_ref_c(fc->ps.sps);
134  frame->pps = av_refstruct_ref_c(fc->ps.pps);
135 
136  // Add LCEVC SEI metadata here, as it's needed in get_buffer()
137  if (fc->sei.common.lcevc.info) {
138  HEVCSEILCEVC *lcevc = &fc->sei.common.lcevc;
139  ret = ff_frame_new_side_data_from_buf(s->avctx, frame->frame,
140  AV_FRAME_DATA_LCEVC, &lcevc->info);
141  if (ret < 0)
142  goto fail;
143  }
144 
146  if (ret < 0)
147  return NULL;
148 
149  frame->rpl = av_refstruct_allocz(s->current_frame.nb_units * sizeof(RefPicListTab));
150  if (!frame->rpl)
151  goto fail;
152  frame->nb_rpl_elems = s->current_frame.nb_units;
153 
154  frame->tab_dmvr_mvf = av_refstruct_pool_get(fc->tab_dmvr_mvf_pool);
155  if (!frame->tab_dmvr_mvf)
156  goto fail;
157 
158  frame->rpl_tab = av_refstruct_pool_get(fc->rpl_tab_pool);
159  if (!frame->rpl_tab)
160  goto fail;
161  frame->ctb_count = pps->ctb_width * pps->ctb_height;
162  for (int j = 0; j < frame->ctb_count; j++)
163  frame->rpl_tab[j] = frame->rpl;
164 
165  win->left_offset = pps->r->pps_scaling_win_left_offset * (1 << sps->hshift[CHROMA]);
166  win->right_offset = pps->r->pps_scaling_win_right_offset * (1 << sps->hshift[CHROMA]);
167  win->top_offset = pps->r->pps_scaling_win_top_offset * (1 << sps->vshift[CHROMA]);
168  win->bottom_offset = pps->r->pps_scaling_win_bottom_offset * (1 << sps->vshift[CHROMA]);
169  frame->ref_width = pps->r->pps_pic_width_in_luma_samples - win->left_offset - win->right_offset;
170  frame->ref_height = pps->r->pps_pic_height_in_luma_samples - win->bottom_offset - win->top_offset;
171 
172  if (fc->sei.frame_field_info.present) {
173  if (fc->sei.frame_field_info.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD)
174  frame->frame->flags |= AV_FRAME_FLAG_TOP_FIELD_FIRST;
175  if (fc->sei.frame_field_info.picture_struct == AV_PICTURE_STRUCTURE_TOP_FIELD ||
176  fc->sei.frame_field_info.picture_struct == AV_PICTURE_STRUCTURE_BOTTOM_FIELD)
177  frame->frame->flags |= AV_FRAME_FLAG_INTERLACED;
178  }
179 
180  frame->progress = alloc_progress();
181  if (!frame->progress)
182  goto fail;
183 
184  ret = ff_hwaccel_frame_priv_alloc(s->avctx, &frame->hwaccel_picture_private);
185  if (ret < 0)
186  goto fail;
187 
188  return frame;
189 fail:
191  return NULL;
192  }
193  av_log(s->avctx, AV_LOG_ERROR, "Error allocating frame, DPB full.\n");
194  return NULL;
195 }
196 
197 static void set_pict_type(AVFrame *frame, const VVCContext *s, const VVCFrameContext *fc)
198 {
199  bool has_b = false, has_inter = false;
200 
201  if (IS_IRAP(s)) {
202  frame->pict_type = AV_PICTURE_TYPE_I;
203  frame->flags |= AV_FRAME_FLAG_KEY;
204  return;
205  }
206 
207  if (fc->ps.ph.r->ph_inter_slice_allowed_flag) {
208  // At this point, fc->slices is not fully initialized; we need to inspect the CBS directly.
209  const CodedBitstreamFragment *current = &s->current_frame;
210  for (int i = 0; i < current->nb_units && !has_b; i++) {
211  const CodedBitstreamUnit *unit = current->units + i;
212  if (unit->content_ref && unit->type <= VVC_RSV_IRAP_11) {
213  const H266RawSliceHeader *rsh = unit->content_ref;
214  has_inter |= !IS_I(rsh);
215  has_b |= IS_B(rsh);
216  }
217  }
218  }
219  if (!has_inter)
220  frame->pict_type = AV_PICTURE_TYPE_I;
221  else if (has_b)
222  frame->pict_type = AV_PICTURE_TYPE_B;
223  else
224  frame->pict_type = AV_PICTURE_TYPE_P;
225 }
226 
228 {
229  const VVCPH *ph= &fc->ps.ph;
230  const int poc = ph->poc;
231  VVCFrame *ref;
232 
233  /* check that this POC doesn't already exist */
234  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
235  VVCFrame *frame = &fc->DPB[i];
236 
237  if (frame->frame->buf[0] && frame->sequence == s->seq_decode &&
238  frame->poc == poc) {
239  av_log(s->avctx, AV_LOG_ERROR, "Duplicate POC in a sequence: %d.\n", poc);
240  return AVERROR_INVALIDDATA;
241  }
242  }
243 
244  ref = alloc_frame(s, fc);
245  if (!ref)
246  return AVERROR(ENOMEM);
247 
248  set_pict_type(ref->frame, s, fc);
249  *frame = ref->frame;
250  fc->ref = ref;
251 
252  if (s->no_output_before_recovery_flag && (IS_RASL(s) || !GDR_IS_RECOVERED(s)))
253  ref->flags = VVC_FRAME_FLAG_SHORT_REF;
254  else if (ph->r->ph_pic_output_flag)
256 
257  if (!ph->r->ph_non_ref_pic_flag)
258  ref->flags |= VVC_FRAME_FLAG_SHORT_REF;
259 
260  ref->poc = poc;
261  ref->sequence = s->seq_decode;
262  ref->frame->crop_left = fc->ps.pps->r->pps_conf_win_left_offset << fc->ps.sps->hshift[CHROMA];
263  ref->frame->crop_right = fc->ps.pps->r->pps_conf_win_right_offset << fc->ps.sps->hshift[CHROMA];
264  ref->frame->crop_top = fc->ps.pps->r->pps_conf_win_top_offset << fc->ps.sps->vshift[CHROMA];
265  ref->frame->crop_bottom = fc->ps.pps->r->pps_conf_win_bottom_offset << fc->ps.sps->vshift[CHROMA];
266 
267  return 0;
268 }
269 
270 int ff_vvc_output_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *out, const int no_output_of_prior_pics_flag, int flush)
271 {
272  const VVCSPS *sps = fc->ps.sps;
273  do {
274  int nb_output = 0;
275  int min_poc = INT_MAX;
276  int min_idx, ret;
277 
278  if (no_output_of_prior_pics_flag) {
279  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
280  VVCFrame *frame = &fc->DPB[i];
281  if (!(frame->flags & VVC_FRAME_FLAG_BUMPING) && frame->poc != fc->ps.ph.poc &&
282  frame->sequence == s->seq_output) {
284  }
285  }
286  }
287 
288  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
289  VVCFrame *frame = &fc->DPB[i];
290  if ((frame->flags & VVC_FRAME_FLAG_OUTPUT) &&
291  frame->sequence == s->seq_output) {
292  nb_output++;
293  if (frame->poc < min_poc || nb_output == 1) {
294  min_poc = frame->poc;
295  min_idx = i;
296  }
297  }
298  }
299 
300  /* wait for more frames before output */
301  if (!flush && s->seq_output == s->seq_decode && sps &&
302  nb_output <= sps->r->sps_dpb_params.dpb_max_num_reorder_pics[sps->r->sps_max_sublayers_minus1])
303  return 0;
304 
305  if (nb_output) {
306  VVCFrame *frame = &fc->DPB[min_idx];
307 
308  if (frame->flags & VVC_FRAME_FLAG_CORRUPT)
309  frame->frame->flags |= AV_FRAME_FLAG_CORRUPT;
310 
311  ret = av_frame_ref(out, frame->needs_fg ? frame->frame_grain : frame->frame);
312 
313  if (!ret && !(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN))
315 
316  if (frame->flags & VVC_FRAME_FLAG_BUMPING)
318  else
320 
321  if (ret < 0)
322  return ret;
323 
324  av_log(s->avctx, AV_LOG_DEBUG,
325  "Output frame with POC %d.\n", frame->poc);
326  return 1;
327  }
328 
329  if (s->seq_output != s->seq_decode)
330  s->seq_output = (s->seq_output + 1) & 0xff;
331  else
332  break;
333  } while (1);
334  return 0;
335 }
336 
338 {
339  const VVCSPS *sps = fc->ps.sps;
340  const int poc = fc->ps.ph.poc;
341  int dpb = 0;
342  int min_poc = INT_MAX;
343 
344  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
345  VVCFrame *frame = &fc->DPB[i];
346  if ((frame->flags) &&
347  frame->sequence == s->seq_output &&
348  frame->poc != poc) {
349  dpb++;
350  }
351  }
352 
353  if (sps && dpb >= sps->r->sps_dpb_params.dpb_max_dec_pic_buffering_minus1[sps->r->sps_max_sublayers_minus1] + 1) {
354  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
355  VVCFrame *frame = &fc->DPB[i];
356  if ((frame->flags) &&
357  frame->sequence == s->seq_output &&
358  frame->poc != poc) {
359  if (frame->flags == VVC_FRAME_FLAG_OUTPUT && frame->poc < min_poc) {
360  min_poc = frame->poc;
361  }
362  }
363  }
364 
365  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
366  VVCFrame *frame = &fc->DPB[i];
367  if (frame->flags & VVC_FRAME_FLAG_OUTPUT &&
368  frame->sequence == s->seq_output &&
369  frame->poc <= min_poc) {
370  frame->flags |= VVC_FRAME_FLAG_BUMPING;
371  }
372  }
373 
374  dpb--;
375  }
376 }
377 
378 static VVCFrame *find_ref_idx(VVCContext *s, VVCFrameContext *fc, int poc, uint8_t use_msb)
379 {
380  const unsigned mask = use_msb ? ~0 : fc->ps.sps->max_pic_order_cnt_lsb - 1;
381 
382  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
383  VVCFrame *ref = &fc->DPB[i];
384  if (ref->frame->buf[0] && ref->sequence == s->seq_decode) {
385  if ((ref->poc & mask) == poc)
386  return ref;
387  }
388  }
389  return NULL;
390 }
391 
392 static void mark_ref(VVCFrame *frame, int flag)
393 {
395  frame->flags |= flag;
396 }
397 
399 {
400  const VVCSPS *sps = fc->ps.sps;
401  const VVCPPS *pps = fc->ps.pps;
402  VVCFrame *frame;
403 
404  frame = alloc_frame(s, fc);
405  if (!frame)
406  return NULL;
407 
408  if (!s->avctx->hwaccel) {
409  if (!sps->pixel_shift) {
410  for (int i = 0; frame->frame->buf[i]; i++)
411  memset(frame->frame->buf[i]->data, 1 << (sps->bit_depth - 1),
412  frame->frame->buf[i]->size);
413  } else {
414  for (int i = 0; frame->frame->data[i]; i++)
415  for (int y = 0; y < (pps->height >> sps->vshift[i]); y++) {
416  uint8_t *dst = frame->frame->data[i] + y * frame->frame->linesize[i];
417  AV_WN16(dst, 1 << (sps->bit_depth - 1));
418  av_memcpy_backptr(dst + 2, 2, 2*(pps->width >> sps->hshift[i]) - 2);
419  }
420  }
421  }
422 
423  frame->poc = poc;
424  frame->sequence = s->seq_decode;
425  frame->flags = VVC_FRAME_FLAG_CORRUPT;
426 
428 
429  return frame;
430 }
431 
432 #define CHECK_MAX(d) (frame->ref_##d * frame->sps->r->sps_pic_##d##_max_in_luma_samples >= ref->ref_##d * (frame->pps->r->pps_pic_##d##_in_luma_samples - max))
433 #define CHECK_SAMPLES(d) (frame->pps->r->pps_pic_##d##_in_luma_samples == ref->pps->r->pps_pic_##d##_in_luma_samples)
434 static int check_candidate_ref(const VVCFrame *frame, const VVCRefPic *refp)
435 {
436  const VVCFrame *ref = refp->ref;
437 
438  if (refp->is_scaled) {
439  const int max = FFMAX(8, frame->sps->min_cb_size_y);
440  return frame->ref_width * 2 >= ref->ref_width &&
441  frame->ref_height * 2 >= ref->ref_height &&
442  frame->ref_width <= ref->ref_width * 8 &&
443  frame->ref_height <= ref->ref_height * 8 &&
445  }
447 }
448 
449 #define RPR_SCALE(f) (((ref->f << 14) + (fc->ref->f >> 1)) / fc->ref->f)
450 /* add a reference with the given poc to the list and mark it as used in DPB */
452  int poc, int ref_flag, uint8_t use_msb)
453 {
454  VVCFrame *ref = find_ref_idx(s, fc, poc, use_msb);
455  VVCRefPic *refp = &list->refs[list->nb_refs];
456 
457  if (ref == fc->ref || list->nb_refs >= VVC_MAX_REF_ENTRIES)
458  return AVERROR_INVALIDDATA;
459 
460  if (!IS_CVSS(s)) {
461  const bool ref_corrupt = !ref || (ref->flags & VVC_FRAME_FLAG_CORRUPT);
462  const bool recovering = s->no_output_before_recovery_flag &&
463  (IS_RASL(s) || !GDR_IS_RECOVERED(s));
464 
465  if (ref_corrupt && !recovering) {
466  if (!(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) &&
467  !(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL))
468  return AVERROR_INVALIDDATA;
469 
470  fc->ref->flags |= VVC_FRAME_FLAG_CORRUPT;
471  }
472  }
473 
474  if (!ref) {
475  ref = generate_missing_ref(s, fc, poc);
476  if (!ref)
477  return AVERROR(ENOMEM);
478  }
479 
480  refp->poc = poc;
481  refp->ref = ref;
482  refp->is_lt = ref_flag & VVC_FRAME_FLAG_LONG_REF;
483  refp->is_scaled = ref->sps->r->sps_num_subpics_minus1 != fc->ref->sps->r->sps_num_subpics_minus1||
484  memcmp(&ref->scaling_win, &fc->ref->scaling_win, sizeof(ref->scaling_win)) ||
485  ref->pps->r->pps_pic_width_in_luma_samples != fc->ref->pps->r->pps_pic_width_in_luma_samples ||
486  ref->pps->r->pps_pic_height_in_luma_samples != fc->ref->pps->r->pps_pic_height_in_luma_samples;
487 
488  if (!check_candidate_ref(fc->ref, refp))
489  return AVERROR_INVALIDDATA;
490 
491  if (refp->is_scaled) {
492  refp->scale[0] = RPR_SCALE(ref_width);
493  refp->scale[1] = RPR_SCALE(ref_height);
494  }
495  list->nb_refs++;
496 
497  mark_ref(ref, ref_flag);
498  return 0;
499 }
500 
502 {
503  VVCFrame *frame = fc->ref;
504  const VVCSH *sh = &sc->sh;
505 
506  if (sc->slice_idx >= frame->nb_rpl_elems)
507  return AVERROR_INVALIDDATA;
508 
509  for (int i = 0; i < sh->num_ctus_in_curr_slice; i++) {
510  const int rs = sh->ctb_addr_in_curr_slice[i];
511  frame->rpl_tab[rs] = frame->rpl + sc->slice_idx;
512  }
513 
514  sc->rpl = frame->rpl_tab[sh->ctb_addr_in_curr_slice[0]]->refPicList;
515 
516  return 0;
517 }
518 
519 static int delta_poc_st(const H266RefPicListStruct *rpls,
520  const int lx, const int i, const VVCSPS *sps)
521 {
522  int abs_delta_poc_st = rpls->abs_delta_poc_st[i];
523  if (!((sps->r->sps_weighted_pred_flag ||
524  sps->r->sps_weighted_bipred_flag) && i != 0))
525  abs_delta_poc_st++;
526  return (1 - 2 * rpls->strp_entry_sign_flag[i]) * abs_delta_poc_st;
527 }
528 
529 static int poc_lt(int *prev_delta_poc_msb, const int poc, const H266RefPicLists *ref_lists,
530  const int lx, const int j, const int max_poc_lsb)
531 {
532  const H266RefPicListStruct *rpls = ref_lists->rpl_ref_list + lx;
533  int lt_poc = rpls->ltrp_in_header_flag ? ref_lists->poc_lsb_lt[lx][j] : rpls->rpls_poc_lsb_lt[j];
534 
535  if (ref_lists->delta_poc_msb_cycle_present_flag[lx][j]) {
536  const uint32_t delta = ref_lists->delta_poc_msb_cycle_lt[lx][j] + *prev_delta_poc_msb;
537  lt_poc += poc - delta * max_poc_lsb - (poc & (max_poc_lsb - 1));
538  *prev_delta_poc_msb = delta;
539  }
540  return lt_poc;
541 }
542 
544 {
545  const VVCSPS *sps = fc->ps.sps;
546  const H266RawPPS *pps = fc->ps.pps->r;
547  const VVCPH *ph = &fc->ps.ph;
548  const H266RawSliceHeader *rsh = sc->sh.r;
549  const int max_poc_lsb = sps->max_pic_order_cnt_lsb;
550  const H266RefPicLists *ref_lists =
551  pps->pps_rpl_info_in_ph_flag ? &ph->r->ph_ref_pic_lists : &rsh->sh_ref_pic_lists;
552  int ret = 0;
553 
554  ret = init_slice_rpl(fc, sc);
555  if (ret < 0)
556  return ret;
557 
558  for (int lx = L0; lx <= L1; lx++) {
559  const H266RefPicListStruct *rpls = ref_lists->rpl_ref_list + lx;
560  RefPicList *rpl = sc->rpl + lx;
561  int poc_base = ph->poc;
562  int prev_delta_poc_msb = 0;
563 
564  rpl->nb_refs = 0;
565  for (int i = 0, j = 0; i < rpls->num_ref_entries; i++) {
566  int poc;
567  if (!rpls->inter_layer_ref_pic_flag[i]) {
568  int use_msb = 1;
569  int ref_flag;
570  if (rpls->st_ref_pic_flag[i]) {
571  poc = poc_base + delta_poc_st(rpls, lx, i, sps);
572  poc_base = poc;
573  ref_flag = VVC_FRAME_FLAG_SHORT_REF;
574  } else {
575  use_msb = ref_lists->delta_poc_msb_cycle_present_flag[lx][j];
576  poc = poc_lt(&prev_delta_poc_msb, ph->poc, ref_lists, lx, j, max_poc_lsb);
577  ref_flag = VVC_FRAME_FLAG_LONG_REF;
578  j++;
579  }
580  ret = add_candidate_ref(s, fc, rpl, poc, ref_flag, use_msb);
581  if (ret < 0)
582  return ret;
583  } else {
584  // OPI_B_3.bit and VPS_A_3.bit should cover this
585  avpriv_report_missing_feature(fc->log_ctx, "Inter layer ref");
587  return ret;
588  }
589  }
590  if (ph->r->ph_temporal_mvp_enabled_flag &&
591  (!rsh->sh_collocated_from_l0_flag) == lx &&
592  rsh->sh_collocated_ref_idx < rpl->nb_refs) {
593  const VVCRefPic *refp = rpl->refs + rsh->sh_collocated_ref_idx;
594  if (refp->is_scaled || refp->ref->sps->ctb_log2_size_y != sps->ctb_log2_size_y)
595  return AVERROR_INVALIDDATA;
596  fc->ref->collocated_ref = refp->ref;
597  }
598  }
599  return 0;
600 }
601 
603 {
604  int ret = 0;
605 
606  /* clear the reference flags on all frames except the current one */
607  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
608  VVCFrame *frame = &fc->DPB[i];
609 
610  if (frame == fc->ref)
611  continue;
612 
613  mark_ref(frame, 0);
614  }
615 
616  if ((ret = ff_vvc_slice_rpl(s, fc, sc)) < 0)
617  goto fail;
618 
619 fail:
620  /* release any frames that are now unused */
621  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
622  ff_vvc_unref_frame(fc, &fc->DPB[i], 0);
623  return ret;
624 }
625 
627 {
630 }
631 
633 {
634  return p->progress[l->vp] > l->y;
635 }
636 
638 {
639  l->next = *prev;
640  *prev = l;
641 }
642 
644 {
645  *prev = l->next;
646  l->next = NULL;
647  return l;
648 }
649 
651 {
653  VVCProgressListener **prev = &p->listener[vp];
654 
655  while (*prev) {
656  if (is_progress_done(p, *prev)) {
657  VVCProgressListener *l = remove_listener(prev, *prev);
658  add_listener(&list, l);
659  } else {
660  prev = &(*prev)->next;
661  }
662  }
663  return list;
664 }
665 
666 void ff_vvc_report_progress(VVCFrame *frame, const VVCProgress vp, const int y)
667 {
668  FrameProgress *p = frame->progress;
670 
671  ff_mutex_lock(&p->lock);
672  if (p->progress[vp] < y) {
673  // Due to the nature of thread scheduling, later progress may reach this point before earlier progress.
674  // Therefore, we only update the progress when p->progress[vp] < y.
675  p->progress[vp] = y;
676  l = get_done_listener(p, vp);
677  ff_cond_signal(&p->cond);
678  }
679  ff_mutex_unlock(&p->lock);
680 
681  while (l) {
682  l->progress_done(l);
683  l = l->next;
684  }
685 }
686 
688 {
689  FrameProgress *p = frame->progress;
690 
691  ff_mutex_lock(&p->lock);
692 
693  if (is_progress_done(p, l)) {
694  ff_mutex_unlock(&p->lock);
695  l->progress_done(l);
696  } else {
697  add_listener(p->listener + l->vp, l);
698  ff_mutex_unlock(&p->lock);
699  }
700 }
flags
const SwsFlags flags[]
Definition: swscale.c:61
VVCSPS
Definition: ps.h:58
L1
F H1 F F H1 F F F F H1<-F-------F-------F v v v H2 H3 H2 ^ ^ ^ F-------F-------F-> H1<-F-------F-------F|||||||||F H1 F|||||||||F H1 Funavailable fullpel samples(outside the picture for example) shall be equalto the closest available fullpel sampleSmaller pel interpolation:--------------------------if diag_mc is set then points which lie on a line between 2 vertically, horizontally or diagonally adjacent halfpel points shall be interpolatedlinearly with rounding to nearest and halfway values rounded up.points which lie on 2 diagonals at the same time should only use the onediagonal not containing the fullpel point F--> O q O<--h1-> O q O<--F v \/v \/v O O O O O O O|/|\|q q q q q|/|\|O O O O O O O ^/\ ^/\ ^ h2--> O q O<--h3-> O q O<--h2 v \/v \/v O O O O O O O|\|/|q q q q q|\|/|O O O O O O O ^/\ ^/\ ^ F--> O q O<--h1-> O q O<--Fthe remaining points shall be bilinearly interpolated from theup to 4 surrounding halfpel and fullpel points, again rounding should be tonearest and halfway values rounded upcompliant Snow decoders MUST support 1-1/8 pel luma and 1/2-1/16 pel chromainterpolation at leastOverlapped block motion compensation:-------------------------------------FIXMELL band prediction:===================Each sample in the LL0 subband is predicted by the median of the left, top andleft+top-topleft samples, samples outside the subband shall be considered tobe 0. To reverse this prediction in the decoder apply the following.for(y=0;y< height;y++){ for(x=0;x< width;x++){ sample[y][x]+=median(sample[y-1][x], sample[y][x-1], sample[y-1][x]+sample[y][x-1]-sample[y-1][x-1]);}}sample[-1][ *]=sample[ *][-1]=0;width, height here are the width and height of the LL0 subband not of the finalvideoDequantization:===============FIXMEWavelet Transform:==================Snow supports 2 wavelet transforms, the symmetric biorthogonal 5/3 integertransform and an integer approximation of the symmetric biorthogonal 9/7daubechies wavelet.2D IDWT(inverse discrete wavelet transform) --------------------------------------------The 2D IDWT applies a 2D filter recursively, each time combining the4 lowest frequency subbands into a single subband until only 1 subbandremains.The 2D filter is done by first applying a 1D filter in the vertical directionand then applying it in the horizontal one. --------------- --------------- --------------- ---------------|LL0|HL0|||||||||||||---+---|HL1||L0|H0|HL1||LL1|HL1|||||LH0|HH0|||||||||||||-------+-------|-> L1 H1 LH1 HH1 LH1 HH1 LH1 HH1 L1
Definition: snow.txt:554
H266RefPicLists::poc_lsb_lt
uint16_t poc_lsb_lt[2][VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:175
CodedBitstreamUnit::content_ref
void * content_ref
If content is reference counted, a RefStruct reference backing content.
Definition: cbs.h:119
VVCSH::num_ctus_in_curr_slice
uint32_t num_ctus_in_curr_slice
NumCtusInCurrSlice.
Definition: ps.h:243
VVCPH
Definition: ps.h:147
ff_mutex_init
static int ff_mutex_init(AVMutex *mutex, const void *attr)
Definition: thread.h:187
VVCPPS
Definition: ps.h:92
add_candidate_ref
static int add_candidate_ref(VVCContext *s, VVCFrameContext *fc, RefPicList *list, int poc, int ref_flag, uint8_t use_msb)
Definition: refs.c:451
VVC_PROGRESS_PIXEL
@ VVC_PROGRESS_PIXEL
Definition: refs.h:46
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
out
FILE * out
Definition: movenc.c:55
FrameProgress::has_cond
uint8_t has_cond
Definition: refs.c:41
thread.h
ff_vvc_report_frame_finished
void ff_vvc_report_frame_finished(VVCFrame *frame)
Definition: refs.c:626
AVRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
VVCProgressListener::vp
VVCProgress vp
Definition: refs.h:54
is_progress_done
static int is_progress_done(const FrameProgress *p, const VVCProgressListener *l)
Definition: refs.c:632
AV_FRAME_DATA_FILM_GRAIN_PARAMS
@ AV_FRAME_DATA_FILM_GRAIN_PARAMS
Film grain parameters for a frame, described by AVFilmGrainParams.
Definition: frame.h:188
HEVCSEILCEVC::info
AVBufferRef * info
Definition: h2645_sei.h:54
VVC_FRAME_FLAG_BUMPING
#define VVC_FRAME_FLAG_BUMPING
Definition: refs.h:31
mask
int mask
Definition: mediacodecdec_common.c:154
ph
static int FUNC() ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
Definition: cbs_h266_syntax_template.c:3037
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
VVCRefPic
Definition: dec.h:47
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
VVCSH::r
const H266RawSliceHeader * r
RefStruct reference.
Definition: ps.h:239
H266RefPicListStruct::st_ref_pic_flag
uint8_t st_ref_pic_flag[VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:164
CodedBitstreamUnit::type
CodedBitstreamUnitType type
Codec-specific type of this unit.
Definition: cbs.h:81
H266RefPicListStruct::ltrp_in_header_flag
uint8_t ltrp_in_header_flag
Definition: cbs_h266.h:162
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
FrameProgress::cond
AVCond cond
Definition: refs.c:39
ff_vvc_slice_rpl
int ff_vvc_slice_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc)
Definition: refs.c:543
H266RefPicListStruct::num_ref_entries
uint8_t num_ref_entries
Definition: cbs_h266.h:161
RefPicList
Definition: hevcdec.h:194
HEVCSEILCEVC
Definition: h2645_sei.h:53
ff_vvc_report_progress
void ff_vvc_report_progress(VVCFrame *frame, const VVCProgress vp, const int y)
Definition: refs.c:666
thread.h
VVCProgress
VVCProgress
Definition: refs.h:44
CodedBitstreamUnit
Coded bitstream unit structure.
Definition: cbs.h:77
VVCRefPic::ref
struct VVCFrame * ref
Definition: dec.h:48
AV_FRAME_FLAG_TOP_FIELD_FIRST
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition: frame.h:655
win
static float win(SuperEqualizerContext *s, float n, int N)
Definition: af_superequalizer.c:119
ff_mutex_unlock
static int ff_mutex_unlock(AVMutex *mutex)
Definition: thread.h:189
AV_CODEC_FLAG_OUTPUT_CORRUPT
#define AV_CODEC_FLAG_OUTPUT_CORRUPT
Output even those frames that might be corrupted.
Definition: avcodec.h:221
H266RefPicListStruct::inter_layer_ref_pic_flag
uint8_t inter_layer_ref_pic_flag[VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:163
fail
#define fail()
Definition: checkasm.h:214
IS_B
#define IS_B(rsh)
Definition: ps.h:40
H266RefPicLists::rpl_ref_list
H266RefPicListStruct rpl_ref_list[2]
Definition: cbs_h266.h:174
CHECK_SAMPLES
#define CHECK_SAMPLES(d)
Definition: refs.c:433
FrameProgress::listener
VVCProgressListener * listener[VVC_PROGRESS_LAST]
Definition: refs.c:37
SliceContext::rpl
RefPicList * rpl
Definition: dec.h:118
RefPicList::nb_refs
int nb_refs
Definition: hevcdec.h:198
refstruct.h
H266RefPicLists::delta_poc_msb_cycle_present_flag
uint8_t delta_poc_msb_cycle_present_flag[2][VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:176
ff_frame_new_side_data_from_buf
int ff_frame_new_side_data_from_buf(const AVCodecContext *avctx, AVFrame *frame, enum AVFrameSideDataType type, AVBufferRef **buf)
Similar to ff_frame_new_side_data, but using an existing buffer ref.
Definition: decode.c:2165
av_refstruct_allocz
static void * av_refstruct_allocz(size_t size)
Equivalent to av_refstruct_alloc_ext(size, 0, NULL, NULL)
Definition: refstruct.h:105
CodedBitstreamFragment::units
CodedBitstreamUnit * units
Pointer to an array of units of length nb_units_allocated.
Definition: cbs.h:175
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
AV_FRAME_FLAG_KEY
#define AV_FRAME_FLAG_KEY
A flag to mark frames that are keyframes.
Definition: frame.h:642
RefPicList::refs
VVCRefPic refs[VVC_MAX_REF_ENTRIES]
Definition: dec.h:58
AVMutex
#define AVMutex
Definition: thread.h:184
av_memcpy_backptr
void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
Overlapping memcpy() implementation.
Definition: mem.c:447
ff_vvc_unref_frame
void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags)
Definition: refs.c:44
RPR_SCALE
#define RPR_SCALE(f)
Definition: refs.c:449
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:129
ff_hwaccel_frame_priv_alloc
int ff_hwaccel_frame_priv_alloc(AVCodecContext *avctx, void **hwaccel_picture_private)
Allocate a hwaccel frame private data if the provided avctx uses a hwaccel method that needs it.
Definition: decode.c:2279
s
#define s(width, name)
Definition: cbs_vp9.c:198
VVC_MAX_REF_ENTRIES
@ VVC_MAX_REF_ENTRIES
Definition: vvc.h:115
SliceContext::slice_idx
int slice_idx
Definition: dec.h:114
AV_GET_BUFFER_FLAG_REF
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
Definition: avcodec.h:411
generate_missing_ref
static VVCFrame * generate_missing_ref(VVCContext *s, VVCFrameContext *fc, int poc)
Definition: refs.c:398
ff_thread_get_buffer
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
Definition: pthread_frame.c:1043
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:494
delta_poc_st
static int delta_poc_st(const H266RefPicListStruct *rpls, const int lx, const int i, const VVCSPS *sps)
Definition: refs.c:519
av_refstruct_alloc_ext
static void * av_refstruct_alloc_ext(size_t size, unsigned flags, void *opaque, void(*free_cb)(AVRefStructOpaque opaque, void *obj))
A wrapper around av_refstruct_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:94
VVCSH
Definition: ps.h:238
ff_vvc_clear_refs
void ff_vvc_clear_refs(VVCFrameContext *fc)
Definition: refs.c:86
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
H266RefPicLists
Definition: cbs_h266.h:171
add_listener
static void add_listener(VVCProgressListener **prev, VVCProgressListener *l)
Definition: refs.c:637
decode.h
AVCond
#define AVCond
Definition: thread.h:192
VVCWindow
Definition: dec.h:66
H266RefPicListStruct::abs_delta_poc_st
uint8_t abs_delta_poc_st[VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:165
AV_PICTURE_STRUCTURE_BOTTOM_FIELD
@ AV_PICTURE_STRUCTURE_BOTTOM_FIELD
coded as bottom field
Definition: avcodec.h:2585
H266RawPPS
Definition: cbs_h266.h:496
VVCSPS::ctb_log2_size_y
uint8_t ctb_log2_size_y
CtbLog2SizeY.
Definition: ps.h:71
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
H266RefPicListStruct::strp_entry_sign_flag
uint8_t strp_entry_sign_flag[VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:166
VVC_FRAME_FLAG_OUTPUT
#define VVC_FRAME_FLAG_OUTPUT
Definition: refs.h:28
AV_PICTURE_STRUCTURE_TOP_FIELD
@ AV_PICTURE_STRUCTURE_TOP_FIELD
coded as top field
Definition: avcodec.h:2584
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:278
set_pict_type
static void set_pict_type(AVFrame *frame, const VVCContext *s, const VVCFrameContext *fc)
Definition: refs.c:197
find_ref_idx
static VVCFrame * find_ref_idx(VVCContext *s, VVCFrameContext *fc, int poc, uint8_t use_msb)
Definition: refs.c:378
L0
#define L0
Definition: hevcdec.h:56
list
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining list
Definition: filter_design.txt:25
flush
void(* flush)(AVBSFContext *ctx)
Definition: dts2pts.c:552
av_refstruct_pool_get
void * av_refstruct_pool_get(AVRefStructPool *pool)
Get an object from the pool, reusing an old one from the pool when available.
Definition: refstruct.c:297
H266RefPicListStruct::rpls_poc_lsb_lt
uint8_t rpls_poc_lsb_lt[VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:167
RefPicListTab
Definition: hevcdec.h:201
init_slice_rpl
static int init_slice_rpl(const VVCFrameContext *fc, SliceContext *sc)
Definition: refs.c:501
VVCRefPic::is_scaled
int is_scaled
RprConstraintsActiveFlag.
Definition: dec.h:53
VVCRefPic::is_lt
int is_lt
Definition: dec.h:50
H266RawSliceHeader::sh_collocated_ref_idx
uint8_t sh_collocated_ref_idx
Definition: cbs_h266.h:803
IS_RASL
#define IS_RASL(s)
Definition: ps.h:35
IS_IRAP
#define IS_IRAP(s)
Definition: hevcdec.h:77
SliceContext
Definition: mss12.h:70
ff_mutex_destroy
static int ff_mutex_destroy(AVMutex *mutex)
Definition: thread.h:190
ff_vvc_flush_dpb
void ff_vvc_flush_dpb(VVCFrameContext *fc)
Definition: refs.c:93
free_progress
static void free_progress(AVRefStructOpaque unused, void *obj)
Definition: refs.c:99
H266RawSliceHeader::sh_collocated_from_l0_flag
uint8_t sh_collocated_from_l0_flag
Definition: cbs_h266.h:802
height
#define height
Definition: dsp.h:89
av_frame_ref
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:278
VVC_FRAME_FLAG_CORRUPT
#define VVC_FRAME_FLAG_CORRUPT
Definition: refs.h:32
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
poc_lt
static int poc_lt(int *prev_delta_poc_msb, const int poc, const H266RefPicLists *ref_lists, const int lx, const int j, const int max_poc_lsb)
Definition: refs.c:529
VVCProgressListener::y
int y
Definition: refs.h:55
VVC_FRAME_FLAG_SHORT_REF
#define VVC_FRAME_FLAG_SHORT_REF
Definition: refs.h:29
AV_FRAME_DATA_LCEVC
@ AV_FRAME_DATA_LCEVC
Raw LCEVC payload data, as a uint8_t array, with NAL emulation bytes intact.
Definition: frame.h:236
H266RefPicListStruct
Definition: cbs_h266.h:160
mark_ref
static void mark_ref(VVCFrame *frame, int flag)
Definition: refs.c:392
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
VVCRefPic::poc
int poc
Definition: dec.h:49
refs.h
CHECK_MAX
#define CHECK_MAX(d)
Definition: refs.c:432
VVC_PROGRESS_LAST
@ VVC_PROGRESS_LAST
Definition: refs.h:47
av_frame_remove_side_data
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
Remove and free all side data instances of the given type.
Definition: frame.c:725
VVCFrame
Definition: dec.h:73
VVCSH::ctb_addr_in_curr_slice
const uint32_t * ctb_addr_in_curr_slice
CtbAddrInCurrSlice.
Definition: ps.h:244
ff_mutex_lock
static int ff_mutex_lock(AVMutex *mutex)
Definition: thread.h:188
ff_vvc_output_frame
int ff_vvc_output_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *out, const int no_output_of_prior_pics_flag, int flush)
Definition: refs.c:270
av_refstruct_unref
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
VVC_PROGRESS_MV
@ VVC_PROGRESS_MV
Definition: refs.h:45
H266RawSliceHeader
Definition: cbs_h266.h:771
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AV_CODEC_FLAG2_SHOW_ALL
#define AV_CODEC_FLAG2_SHOW_ALL
Show all frames before the first keyframe.
Definition: avcodec.h:360
AV_FRAME_FLAG_CORRUPT
#define AV_FRAME_FLAG_CORRUPT
The frame data may be corrupted, e.g.
Definition: frame.h:638
alloc_progress
static FrameProgress * alloc_progress(void)
Definition: refs.c:109
delta
float delta
Definition: vorbis_enc_data.h:430
FrameProgress::progress
atomic_int progress[VVC_PROGRESS_LAST]
Definition: refs.c:36
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:496
VVCProgressListener::next
VVCProgressListener * next
Definition: refs.h:57
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:650
GDR_IS_RECOVERED
#define GDR_IS_RECOVERED(s)
Definition: ps.h:43
H266RefPicLists::delta_poc_msb_cycle_lt
uint16_t delta_poc_msb_cycle_lt[2][VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:177
ret
ret
Definition: filter_design.txt:187
VVC_RSV_IRAP_11
@ VVC_RSV_IRAP_11
Definition: vvc.h:40
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
CHROMA
@ CHROMA
Definition: vf_waveform.c:49
sps
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
Definition: cbs_h264_syntax_template.c:260
flag
#define flag(name)
Definition: cbs_av1.c:496
check_candidate_ref
static int check_candidate_ref(const VVCFrame *frame, const VVCRefPic *refp)
Definition: refs.c:434
VVCProgressListener
Definition: refs.h:53
remove_listener
static VVCProgressListener * remove_listener(VVCProgressListener **prev, VVCProgressListener *l)
Definition: refs.c:643
av_refstruct_ref_c
const void * av_refstruct_ref_c(const void *obj)
Analog of av_refstruct_ref(), but for constant objects.
Definition: refstruct.c:149
AV_PICTURE_TYPE_B
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition: avutil.h:280
FrameProgress::lock
AVMutex lock
Definition: refs.c:38
FrameProgress
Definition: refs.c:35
VVC_FRAME_FLAG_LONG_REF
#define VVC_FRAME_FLAG_LONG_REF
Definition: refs.h:30
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
ff_cond_signal
static int ff_cond_signal(AVCond *cond)
Definition: thread.h:196
pps
uint64_t pps
Definition: dovi_rpuenc.c:36
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
ff_vvc_set_new_ref
int ff_vvc_set_new_ref(VVCContext *s, VVCFrameContext *fc, AVFrame **frame)
Definition: refs.c:227
ff_vvc_get_ref_list
const RefPicList * ff_vvc_get_ref_list(const VVCFrameContext *fc, const VVCFrame *ref, int x0, int y0)
Definition: refs.c:76
FrameProgress::has_lock
uint8_t has_lock
Definition: refs.c:40
ff_vvc_frame_rpl
int ff_vvc_frame_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc)
Definition: refs.c:602
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:279
mem.h
alloc_frame
static VVCFrame * alloc_frame(VVCContext *s, VVCFrameContext *fc)
Definition: refs.c:122
get_done_listener
static VVCProgressListener * get_done_listener(FrameProgress *p, const VVCProgress vp)
Definition: refs.c:650
ff_cond_destroy
static int ff_cond_destroy(AVCond *cond)
Definition: thread.h:195
VVCProgressListener::progress_done
progress_done_fn progress_done
Definition: refs.h:56
SliceContext::sh
VVCSH sh
Definition: dec.h:115
VVCFrameContext
Definition: dec.h:122
H266RawSliceHeader::sh_ref_pic_lists
H266RefPicLists sh_ref_pic_lists
Definition: cbs_h266.h:797
IS_I
#define IS_I(rsh)
Definition: ps.h:38
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_cond_init
static int ff_cond_init(AVCond *cond, const void *attr)
Definition: thread.h:194
width
#define width
Definition: dsp.h:89
IS_CVSS
#define IS_CVSS(s)
Definition: ps.h:33
ff_vvc_add_progress_listener
void ff_vvc_add_progress_listener(VVCFrame *frame, VVCProgressListener *l)
Definition: refs.c:687
VVCFrame::sps
const VVCSPS * sps
RefStruct reference.
Definition: dec.h:76
AV_CODEC_EXPORT_DATA_FILM_GRAIN
#define AV_CODEC_EXPORT_DATA_FILM_GRAIN
Decoding only.
Definition: avcodec.h:400
CodedBitstreamFragment::nb_units
int nb_units
Number of units in this fragment.
Definition: cbs.h:160
ff_vvc_bump_frame
void ff_vvc_bump_frame(VVCContext *s, VVCFrameContext *fc)
Definition: refs.c:337
VVCRefPic::scale
int scale[2]
RefPicScale[].
Definition: dec.h:54
VVCContext
Definition: dec.h:218
AV_WN16
#define AV_WN16(p, v)
Definition: intreadwrite.h:368