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);
57  av_refstruct_unref(&frame->progress);
58 
59  av_refstruct_unref(&frame->tab_dmvr_mvf);
60 
62  frame->nb_rpl_elems = 0;
63  av_refstruct_unref(&frame->rpl_tab);
64 
65  frame->collocated_ref = NULL;
66  av_refstruct_unref(&frame->hwaccel_picture_private);
67  }
68 }
69 
70 const RefPicList *ff_vvc_get_ref_list(const VVCFrameContext *fc, const VVCFrame *ref, int x0, int y0)
71 {
72  const int x_cb = x0 >> fc->ps.sps->ctb_log2_size_y;
73  const int y_cb = y0 >> fc->ps.sps->ctb_log2_size_y;
74  const int pic_width_cb = fc->ps.pps->ctb_width;
75  const int ctb_addr_rs = y_cb * pic_width_cb + x_cb;
76 
77  return (const RefPicList *)ref->rpl_tab[ctb_addr_rs];
78 }
79 
81 {
82  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
83  ff_vvc_unref_frame(fc, &fc->DPB[i],
85 }
86 
88 {
89  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
90  ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
91 }
92 
93 static void free_progress(AVRefStructOpaque unused, void *obj)
94 {
95  FrameProgress *p = (FrameProgress *)obj;
96 
97  if (p->has_cond)
98  ff_cond_destroy(&p->cond);
99  if (p->has_lock)
100  ff_mutex_destroy(&p->lock);
101 }
102 
104 {
106 
107  if (p) {
108  p->has_lock = !ff_mutex_init(&p->lock, NULL);
109  p->has_cond = !ff_cond_init(&p->cond, NULL);
110  if (!p->has_lock || !p->has_cond)
111  av_refstruct_unref(&p);
112  }
113  return p;
114 }
115 
117 {
118  const VVCSPS *sps = fc->ps.sps;
119  const VVCPPS *pps = fc->ps.pps;
120  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
121  int ret;
122  VVCFrame *frame = &fc->DPB[i];
123  VVCWindow *win = &frame->scaling_win;
124  if (frame->frame->buf[0])
125  continue;
126 
127  frame->sps = av_refstruct_ref_c(fc->ps.sps);
128  frame->pps = av_refstruct_ref_c(fc->ps.pps);
129 
131  if (ret < 0)
132  return NULL;
133 
134  frame->rpl = av_refstruct_allocz(s->current_frame.nb_units * sizeof(RefPicListTab));
135  if (!frame->rpl)
136  goto fail;
137  frame->nb_rpl_elems = s->current_frame.nb_units;
138 
139  frame->tab_dmvr_mvf = av_refstruct_pool_get(fc->tab_dmvr_mvf_pool);
140  if (!frame->tab_dmvr_mvf)
141  goto fail;
142 
143  frame->rpl_tab = av_refstruct_pool_get(fc->rpl_tab_pool);
144  if (!frame->rpl_tab)
145  goto fail;
146  frame->ctb_count = pps->ctb_width * pps->ctb_height;
147  for (int j = 0; j < frame->ctb_count; j++)
148  frame->rpl_tab[j] = frame->rpl;
149 
150  win->left_offset = pps->r->pps_scaling_win_left_offset << sps->hshift[CHROMA];
151  win->right_offset = pps->r->pps_scaling_win_right_offset << sps->hshift[CHROMA];
152  win->top_offset = pps->r->pps_scaling_win_top_offset << sps->vshift[CHROMA];
153  win->bottom_offset = pps->r->pps_scaling_win_bottom_offset << sps->vshift[CHROMA];
154  frame->ref_width = pps->r->pps_pic_width_in_luma_samples - win->left_offset - win->right_offset;
155  frame->ref_height = pps->r->pps_pic_height_in_luma_samples - win->bottom_offset - win->top_offset;
156 
157  frame->progress = alloc_progress();
158  if (!frame->progress)
159  goto fail;
160 
161  ret = ff_hwaccel_frame_priv_alloc(s->avctx, &frame->hwaccel_picture_private);
162  if (ret < 0)
163  goto fail;
164 
165  return frame;
166 fail:
168  return NULL;
169  }
170  av_log(s->avctx, AV_LOG_ERROR, "Error allocating frame, DPB full.\n");
171  return NULL;
172 }
173 
174 static void set_pict_type(AVFrame *frame, const VVCContext *s, const VVCFrameContext *fc)
175 {
176  bool has_b = false, has_inter = false;
177 
178  if (IS_IRAP(s)) {
179  frame->pict_type = AV_PICTURE_TYPE_I;
180  frame->flags |= AV_FRAME_FLAG_KEY;
181  return;
182  }
183 
184  if (fc->ps.ph.r->ph_inter_slice_allowed_flag) {
185  // At this point, fc->slices is not fully initialized; we need to inspect the CBS directly.
186  const CodedBitstreamFragment *current = &s->current_frame;
187  for (int i = 0; i < current->nb_units && !has_b; i++) {
188  const CodedBitstreamUnit *unit = current->units + i;
189  if (unit->type <= VVC_RSV_IRAP_11) {
190  const H266RawSliceHeader *rsh = unit->content_ref;
191  has_inter |= !IS_I(rsh);
192  has_b |= IS_B(rsh);
193  }
194  }
195  }
196  if (!has_inter)
197  frame->pict_type = AV_PICTURE_TYPE_I;
198  else if (has_b)
199  frame->pict_type = AV_PICTURE_TYPE_B;
200  else
201  frame->pict_type = AV_PICTURE_TYPE_P;
202 }
203 
205 {
206  const VVCPH *ph= &fc->ps.ph;
207  const int poc = ph->poc;
208  VVCFrame *ref;
209 
210  /* check that this POC doesn't already exist */
211  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
212  VVCFrame *frame = &fc->DPB[i];
213 
214  if (frame->frame->buf[0] && frame->sequence == s->seq_decode &&
215  frame->poc == poc) {
216  av_log(s->avctx, AV_LOG_ERROR, "Duplicate POC in a sequence: %d.\n", poc);
217  return AVERROR_INVALIDDATA;
218  }
219  }
220 
221  ref = alloc_frame(s, fc);
222  if (!ref)
223  return AVERROR(ENOMEM);
224 
225  set_pict_type(ref->frame, s, fc);
226  *frame = ref->frame;
227  fc->ref = ref;
228 
229  if (s->no_output_before_recovery_flag && (IS_RASL(s) || !GDR_IS_RECOVERED(s)))
230  ref->flags = VVC_FRAME_FLAG_SHORT_REF;
231  else if (ph->r->ph_pic_output_flag)
233 
234  if (!ph->r->ph_non_ref_pic_flag)
235  ref->flags |= VVC_FRAME_FLAG_SHORT_REF;
236 
237  ref->poc = poc;
238  ref->sequence = s->seq_decode;
239  ref->frame->crop_left = fc->ps.pps->r->pps_conf_win_left_offset << fc->ps.sps->hshift[CHROMA];
240  ref->frame->crop_right = fc->ps.pps->r->pps_conf_win_right_offset << fc->ps.sps->hshift[CHROMA];
241  ref->frame->crop_top = fc->ps.pps->r->pps_conf_win_top_offset << fc->ps.sps->vshift[CHROMA];
242  ref->frame->crop_bottom = fc->ps.pps->r->pps_conf_win_bottom_offset << fc->ps.sps->vshift[CHROMA];
243 
244  return 0;
245 }
246 
247 int ff_vvc_output_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *out, const int no_output_of_prior_pics_flag, int flush)
248 {
249  const VVCSPS *sps = fc->ps.sps;
250  do {
251  int nb_output = 0;
252  int min_poc = INT_MAX;
253  int min_idx, ret;
254 
255  if (no_output_of_prior_pics_flag) {
256  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
257  VVCFrame *frame = &fc->DPB[i];
258  if (!(frame->flags & VVC_FRAME_FLAG_BUMPING) && frame->poc != fc->ps.ph.poc &&
259  frame->sequence == s->seq_output) {
261  }
262  }
263  }
264 
265  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
266  VVCFrame *frame = &fc->DPB[i];
267  if ((frame->flags & VVC_FRAME_FLAG_OUTPUT) &&
268  frame->sequence == s->seq_output) {
269  nb_output++;
270  if (frame->poc < min_poc || nb_output == 1) {
271  min_poc = frame->poc;
272  min_idx = i;
273  }
274  }
275  }
276 
277  /* wait for more frames before output */
278  if (!flush && s->seq_output == s->seq_decode && sps &&
279  nb_output <= sps->r->sps_dpb_params.dpb_max_num_reorder_pics[sps->r->sps_max_sublayers_minus1])
280  return 0;
281 
282  if (nb_output) {
283  VVCFrame *frame = &fc->DPB[min_idx];
284 
285  if (frame->flags & VVC_FRAME_FLAG_CORRUPT)
286  frame->frame->flags |= AV_FRAME_FLAG_CORRUPT;
287 
288  ret = av_frame_ref(out, frame->frame);
289  if (frame->flags & VVC_FRAME_FLAG_BUMPING)
291  else
293  if (ret < 0)
294  return ret;
295 
296  av_log(s->avctx, AV_LOG_DEBUG,
297  "Output frame with POC %d.\n", frame->poc);
298  return 1;
299  }
300 
301  if (s->seq_output != s->seq_decode)
302  s->seq_output = (s->seq_output + 1) & 0xff;
303  else
304  break;
305  } while (1);
306  return 0;
307 }
308 
310 {
311  const VVCSPS *sps = fc->ps.sps;
312  const int poc = fc->ps.ph.poc;
313  int dpb = 0;
314  int min_poc = INT_MAX;
315 
316  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
317  VVCFrame *frame = &fc->DPB[i];
318  if ((frame->flags) &&
319  frame->sequence == s->seq_output &&
320  frame->poc != poc) {
321  dpb++;
322  }
323  }
324 
325  if (sps && dpb >= sps->r->sps_dpb_params.dpb_max_dec_pic_buffering_minus1[sps->r->sps_max_sublayers_minus1] + 1) {
326  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
327  VVCFrame *frame = &fc->DPB[i];
328  if ((frame->flags) &&
329  frame->sequence == s->seq_output &&
330  frame->poc != poc) {
331  if (frame->flags == VVC_FRAME_FLAG_OUTPUT && frame->poc < min_poc) {
332  min_poc = frame->poc;
333  }
334  }
335  }
336 
337  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
338  VVCFrame *frame = &fc->DPB[i];
339  if (frame->flags & VVC_FRAME_FLAG_OUTPUT &&
340  frame->sequence == s->seq_output &&
341  frame->poc <= min_poc) {
342  frame->flags |= VVC_FRAME_FLAG_BUMPING;
343  }
344  }
345 
346  dpb--;
347  }
348 }
349 
350 static VVCFrame *find_ref_idx(VVCContext *s, VVCFrameContext *fc, int poc, uint8_t use_msb)
351 {
352  const unsigned mask = use_msb ? ~0 : fc->ps.sps->max_pic_order_cnt_lsb - 1;
353 
354  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
355  VVCFrame *ref = &fc->DPB[i];
356  if (ref->frame->buf[0] && ref->sequence == s->seq_decode) {
357  if ((ref->poc & mask) == poc)
358  return ref;
359  }
360  }
361  return NULL;
362 }
363 
364 static void mark_ref(VVCFrame *frame, int flag)
365 {
367  frame->flags |= flag;
368 }
369 
371 {
372  const VVCSPS *sps = fc->ps.sps;
373  const VVCPPS *pps = fc->ps.pps;
374  VVCFrame *frame;
375 
376  frame = alloc_frame(s, fc);
377  if (!frame)
378  return NULL;
379 
380  if (!s->avctx->hwaccel) {
381  if (!sps->pixel_shift) {
382  for (int i = 0; frame->frame->buf[i]; i++)
383  memset(frame->frame->buf[i]->data, 1 << (sps->bit_depth - 1),
384  frame->frame->buf[i]->size);
385  } else {
386  for (int i = 0; frame->frame->data[i]; i++)
387  for (int y = 0; y < (pps->height >> sps->vshift[i]); y++) {
388  uint8_t *dst = frame->frame->data[i] + y * frame->frame->linesize[i];
389  AV_WN16(dst, 1 << (sps->bit_depth - 1));
390  av_memcpy_backptr(dst + 2, 2, 2*(pps->width >> sps->hshift[i]) - 2);
391  }
392  }
393  }
394 
395  frame->poc = poc;
396  frame->sequence = s->seq_decode;
397  frame->flags = VVC_FRAME_FLAG_CORRUPT;
398 
400 
401  return frame;
402 }
403 
404 #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))
405 #define CHECK_SAMPLES(d) (frame->pps->r->pps_pic_##d##_in_luma_samples == ref->pps->r->pps_pic_##d##_in_luma_samples)
406 static int check_candidate_ref(const VVCFrame *frame, const VVCRefPic *refp)
407 {
408  const VVCFrame *ref = refp->ref;
409 
410  if (refp->is_scaled) {
411  const int max = FFMAX(8, frame->sps->min_cb_size_y);
412  return frame->ref_width * 2 >= ref->ref_width &&
413  frame->ref_height * 2 >= ref->ref_height &&
414  frame->ref_width <= ref->ref_width * 8 &&
415  frame->ref_height <= ref->ref_height * 8 &&
417  }
419 }
420 
421 #define RPR_SCALE(f) (((ref->f << 14) + (fc->ref->f >> 1)) / fc->ref->f)
422 /* add a reference with the given poc to the list and mark it as used in DPB */
424  int poc, int ref_flag, uint8_t use_msb)
425 {
426  VVCFrame *ref = find_ref_idx(s, fc, poc, use_msb);
427  VVCRefPic *refp = &list->refs[list->nb_refs];
428 
429  if (ref == fc->ref || list->nb_refs >= VVC_MAX_REF_ENTRIES)
430  return AVERROR_INVALIDDATA;
431 
432  if (!IS_CVSS(s)) {
433  const bool ref_corrupt = !ref || (ref->flags & VVC_FRAME_FLAG_CORRUPT);
434  const bool recovering = s->no_output_before_recovery_flag && !GDR_IS_RECOVERED(s);
435 
436  if (ref_corrupt && !recovering) {
437  if (!(s->avctx->flags & AV_CODEC_FLAG_OUTPUT_CORRUPT) &&
438  !(s->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL))
439  return AVERROR_INVALIDDATA;
440 
441  fc->ref->flags |= VVC_FRAME_FLAG_CORRUPT;
442  }
443  }
444 
445  if (!ref) {
446  ref = generate_missing_ref(s, fc, poc);
447  if (!ref)
448  return AVERROR(ENOMEM);
449  }
450 
451  refp->poc = poc;
452  refp->ref = ref;
453  refp->is_lt = ref_flag & VVC_FRAME_FLAG_LONG_REF;
454  refp->is_scaled = ref->sps->r->sps_num_subpics_minus1 != fc->ref->sps->r->sps_num_subpics_minus1||
455  memcmp(&ref->scaling_win, &fc->ref->scaling_win, sizeof(ref->scaling_win)) ||
456  ref->pps->r->pps_pic_width_in_luma_samples != fc->ref->pps->r->pps_pic_width_in_luma_samples ||
457  ref->pps->r->pps_pic_height_in_luma_samples != fc->ref->pps->r->pps_pic_height_in_luma_samples;
458 
459  if (!check_candidate_ref(fc->ref, refp))
460  return AVERROR_INVALIDDATA;
461 
462  if (refp->is_scaled) {
463  refp->scale[0] = RPR_SCALE(ref_width);
464  refp->scale[1] = RPR_SCALE(ref_height);
465  }
466  list->nb_refs++;
467 
468  mark_ref(ref, ref_flag);
469  return 0;
470 }
471 
473 {
474  VVCFrame *frame = fc->ref;
475  const VVCSH *sh = &sc->sh;
476 
477  if (sc->slice_idx >= frame->nb_rpl_elems)
478  return AVERROR_INVALIDDATA;
479 
480  for (int i = 0; i < sh->num_ctus_in_curr_slice; i++) {
481  const int rs = sh->ctb_addr_in_curr_slice[i];
482  frame->rpl_tab[rs] = frame->rpl + sc->slice_idx;
483  }
484 
485  sc->rpl = frame->rpl_tab[sh->ctb_addr_in_curr_slice[0]]->refPicList;
486 
487  return 0;
488 }
489 
490 static int delta_poc_st(const H266RefPicListStruct *rpls,
491  const int lx, const int i, const VVCSPS *sps)
492 {
493  int abs_delta_poc_st = rpls->abs_delta_poc_st[i];
494  if (!((sps->r->sps_weighted_pred_flag ||
495  sps->r->sps_weighted_bipred_flag) && i != 0))
496  abs_delta_poc_st++;
497  return (1 - 2 * rpls->strp_entry_sign_flag[i]) * abs_delta_poc_st;
498 }
499 
500 static int poc_lt(int *prev_delta_poc_msb, const int poc, const H266RefPicLists *ref_lists,
501  const int lx, const int j, const int max_poc_lsb)
502 {
503  const H266RefPicListStruct *rpls = ref_lists->rpl_ref_list + lx;
504  int lt_poc = rpls->ltrp_in_header_flag ? ref_lists->poc_lsb_lt[lx][j] : rpls->rpls_poc_lsb_lt[j];
505 
506  if (ref_lists->delta_poc_msb_cycle_present_flag[lx][j]) {
507  const uint32_t delta = ref_lists->delta_poc_msb_cycle_lt[lx][j] + *prev_delta_poc_msb;
508  lt_poc += poc - delta * max_poc_lsb - (poc & (max_poc_lsb - 1));
509  *prev_delta_poc_msb = delta;
510  }
511  return lt_poc;
512 }
513 
515 {
516  const VVCSPS *sps = fc->ps.sps;
517  const H266RawPPS *pps = fc->ps.pps->r;
518  const VVCPH *ph = &fc->ps.ph;
519  const H266RawSliceHeader *rsh = sc->sh.r;
520  const int max_poc_lsb = sps->max_pic_order_cnt_lsb;
521  const H266RefPicLists *ref_lists =
522  pps->pps_rpl_info_in_ph_flag ? &ph->r->ph_ref_pic_lists : &rsh->sh_ref_pic_lists;
523  int ret = 0;
524 
525  ret = init_slice_rpl(fc, sc);
526  if (ret < 0)
527  return ret;
528 
529  for (int lx = L0; lx <= L1; lx++) {
530  const H266RefPicListStruct *rpls = ref_lists->rpl_ref_list + lx;
531  RefPicList *rpl = sc->rpl + lx;
532  int poc_base = ph->poc;
533  int prev_delta_poc_msb = 0;
534 
535  rpl->nb_refs = 0;
536  for (int i = 0, j = 0; i < rpls->num_ref_entries; i++) {
537  int poc;
538  if (!rpls->inter_layer_ref_pic_flag[i]) {
539  int use_msb = 1;
540  int ref_flag;
541  if (rpls->st_ref_pic_flag[i]) {
542  poc = poc_base + delta_poc_st(rpls, lx, i, sps);
543  poc_base = poc;
544  ref_flag = VVC_FRAME_FLAG_SHORT_REF;
545  } else {
546  use_msb = ref_lists->delta_poc_msb_cycle_present_flag[lx][j];
547  poc = poc_lt(&prev_delta_poc_msb, ph->poc, ref_lists, lx, j, max_poc_lsb);
548  ref_flag = VVC_FRAME_FLAG_LONG_REF;
549  j++;
550  }
551  ret = add_candidate_ref(s, fc, rpl, poc, ref_flag, use_msb);
552  if (ret < 0)
553  return ret;
554  } else {
555  // OPI_B_3.bit and VPS_A_3.bit should cover this
556  avpriv_report_missing_feature(fc->log_ctx, "Inter layer ref");
558  return ret;
559  }
560  }
561  if (ph->r->ph_temporal_mvp_enabled_flag &&
562  (!rsh->sh_collocated_from_l0_flag) == lx &&
563  rsh->sh_collocated_ref_idx < rpl->nb_refs) {
564  const VVCRefPic *refp = rpl->refs + rsh->sh_collocated_ref_idx;
565  if (refp->is_scaled || refp->ref->sps->ctb_log2_size_y != sps->ctb_log2_size_y)
566  return AVERROR_INVALIDDATA;
567  fc->ref->collocated_ref = refp->ref;
568  }
569  }
570  return 0;
571 }
572 
574 {
575  int ret = 0;
576 
577  /* clear the reference flags on all frames except the current one */
578  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
579  VVCFrame *frame = &fc->DPB[i];
580 
581  if (frame == fc->ref)
582  continue;
583 
584  mark_ref(frame, 0);
585  }
586 
587  if ((ret = ff_vvc_slice_rpl(s, fc, sc)) < 0)
588  goto fail;
589 
590 fail:
591  /* release any frames that are now unused */
592  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
593  ff_vvc_unref_frame(fc, &fc->DPB[i], 0);
594  return ret;
595 }
596 
598 {
601 }
602 
603 static int is_progress_done(const FrameProgress *p, const VVCProgressListener *l)
604 {
605  return p->progress[l->vp] > l->y;
606 }
607 
609 {
610  l->next = *prev;
611  *prev = l;
612 }
613 
615 {
616  *prev = l->next;
617  l->next = NULL;
618  return l;
619 }
620 
622 {
624  VVCProgressListener **prev = &p->listener[vp];
625 
626  while (*prev) {
627  if (is_progress_done(p, *prev)) {
628  VVCProgressListener *l = remove_listener(prev, *prev);
629  add_listener(&list, l);
630  } else {
631  prev = &(*prev)->next;
632  }
633  }
634  return list;
635 }
636 
637 void ff_vvc_report_progress(VVCFrame *frame, const VVCProgress vp, const int y)
638 {
639  FrameProgress *p = frame->progress;
641 
642  ff_mutex_lock(&p->lock);
643  if (p->progress[vp] < y) {
644  // Due to the nature of thread scheduling, later progress may reach this point before earlier progress.
645  // Therefore, we only update the progress when p->progress[vp] < y.
646  p->progress[vp] = y;
647  l = get_done_listener(p, vp);
648  ff_cond_signal(&p->cond);
649  }
650  ff_mutex_unlock(&p->lock);
651 
652  while (l) {
653  l->progress_done(l);
654  l = l->next;
655  }
656 }
657 
659 {
660  FrameProgress *p = frame->progress;
661 
662  ff_mutex_lock(&p->lock);
663 
664  if (is_progress_done(p, l)) {
665  ff_mutex_unlock(&p->lock);
666  l->progress_done(l);
667  } else {
668  add_listener(p->listener + l->vp, l);
669  ff_mutex_unlock(&p->lock);
670  }
671 }
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:112
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:423
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:597
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:603
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:3043
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:410
VVCRefPic
Definition: dec.h:45
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:74
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:472
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:514
H266RefPicListStruct::num_ref_entries
uint8_t num_ref_entries
Definition: cbs_h266.h:161
RefPicList
Definition: hevcdec.h:192
ff_vvc_report_progress
void ff_vvc_report_progress(VVCFrame *frame, const VVCProgress vp, const int y)
Definition: refs.c:637
thread.h
VVCProgress
VVCProgress
Definition: refs.h:44
CodedBitstreamUnit
Coded bitstream unit structure.
Definition: cbs.h:70
VVCRefPic::ref
struct VVCFrame * ref
Definition: dec.h:46
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:232
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:193
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:405
FrameProgress::listener
VVCProgressListener * listener[VVC_PROGRESS_LAST]
Definition: refs.c:37
SliceContext::rpl
RefPicList * rpl
Definition: dec.h:113
RefPicList::nb_refs
int nb_refs
Definition: hevcdec.h:196
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
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:168
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
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:661
RefPicList::refs
VVCRefPic refs[VVC_MAX_REF_ENTRIES]
Definition: dec.h:56
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:421
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:122
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:2251
s
#define s(width, name)
Definition: cbs_vp9.c:198
SliceContext::slice_idx
int slice_idx
Definition: dec.h:109
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:431
generate_missing_ref
static VVCFrame * generate_missing_ref(VVCContext *s, VVCFrameContext *fc, int poc)
Definition: refs.c:370
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:1053
delta_poc_st
static int delta_poc_st(const H266RefPicListStruct *rpls, const int lx, const int i, const VVCSPS *sps)
Definition: refs.c:490
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:80
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:230
H266RefPicLists
Definition: cbs_h266.h:171
add_listener
static void add_listener(VVCProgressListener **prev, VVCProgressListener *l)
Definition: refs.c:608
decode.h
AVCond
#define AVCond
Definition: thread.h:192
VVCWindow
Definition: dec.h:64
H266RefPicListStruct::abs_delta_poc_st
uint8_t abs_delta_poc_st[VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:165
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_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
set_pict_type
static void set_pict_type(AVFrame *frame, const VVCContext *s, const VVCFrameContext *fc)
Definition: refs.c:174
find_ref_idx
static VVCFrame * find_ref_idx(VVCContext *s, VVCFrameContext *fc, int poc, uint8_t use_msb)
Definition: refs.c:350
L0
#define L0
Definition: hevcdec.h:58
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:370
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:199
init_slice_rpl
static int init_slice_rpl(const VVCFrameContext *fc, SliceContext *sc)
Definition: refs.c:472
VVCRefPic::is_scaled
int is_scaled
RprConstraintsActiveFlag.
Definition: dec.h:51
VVCRefPic::is_lt
int is_lt
Definition: dec.h:48
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:79
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:87
free_progress
static void free_progress(AVRefStructOpaque unused, void *obj)
Definition: refs.c:93
H266RawSliceHeader::sh_collocated_from_l0_flag
uint8_t sh_collocated_from_l0_flag
Definition: cbs_h266.h:802
height
#define height
Definition: dsp.h:85
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:401
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:83
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:500
VVCProgressListener::y
int y
Definition: refs.h:55
VVC_FRAME_FLAG_SHORT_REF
#define VVC_FRAME_FLAG_SHORT_REF
Definition: refs.h:29
H266RefPicListStruct
Definition: cbs_h266.h:160
mark_ref
static void mark_ref(VVCFrame *frame, int flag)
Definition: refs.c:364
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:47
refs.h
CHECK_MAX
#define CHECK_MAX(d)
Definition: refs.c:404
VVC_PROGRESS_LAST
@ VVC_PROGRESS_LAST
Definition: refs.h:47
VVCFrame
Definition: dec.h:71
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:247
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
VVC_MAX_REF_ENTRIES
@ VVC_MAX_REF_ENTRIES
Definition: vvc.h:115
flag
#define flag(name)
Definition: cbs_av1.c:474
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:380
AV_FRAME_FLAG_CORRUPT
#define AV_FRAME_FLAG_CORRUPT
The frame data may be corrupted, e.g.
Definition: frame.h:657
alloc_progress
static FrameProgress * alloc_progress(void)
Definition: refs.c:103
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:623
VVCProgressListener::next
VVCProgressListener * next
Definition: refs.h:57
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:264
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
check_candidate_ref
static int check_candidate_ref(const VVCFrame *frame, const VVCRefPic *refp)
Definition: refs.c:406
VVCProgressListener
Definition: refs.h:53
remove_listener
static VVCProgressListener * remove_listener(VVCProgressListener **prev, VVCProgressListener *l)
Definition: refs.c:614
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:281
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:35
ff_vvc_set_new_ref
int ff_vvc_set_new_ref(VVCContext *s, VVCFrameContext *fc, AVFrame **frame)
Definition: refs.c:204
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:70
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:573
AV_PICTURE_TYPE_P
@ AV_PICTURE_TYPE_P
Predicted.
Definition: avutil.h:280
mem.h
alloc_frame
static VVCFrame * alloc_frame(VVCContext *s, VVCFrameContext *fc)
Definition: refs.c:116
get_done_listener
static VVCProgressListener * get_done_listener(FrameProgress *p, const VVCProgress vp)
Definition: refs.c:621
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:110
VVCFrameContext
Definition: dec.h:117
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
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
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:85
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:658
VVCFrame::sps
const VVCSPS * sps
RefStruct reference.
Definition: dec.h:74
CodedBitstreamFragment::nb_units
int nb_units
Number of units in this fragment.
Definition: cbs.h:153
ff_vvc_bump_frame
void ff_vvc_bump_frame(VVCContext *s, VVCFrameContext *fc)
Definition: refs.c:309
VVCRefPic::scale
int scale[2]
RefPicScale[].
Definition: dec.h:52
VVCContext
Definition: dec.h:212
AV_WN16
#define AV_WN16(p, v)
Definition: intreadwrite.h:368