FFmpeg
dec.c
Go to the documentation of this file.
1 /*
2  * VVC video decoder
3  *
4  * Copyright (C) 2021 Nuo Mi
5  * Copyright (C) 2022 Xu Mu
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
24 #include "libavcodec/decode.h"
25 #include "libavcodec/profiles.h"
26 #include "libavcodec/refstruct.h"
27 #include "libavutil/cpu.h"
28 #include "libavutil/mem.h"
29 #include "libavutil/thread.h"
30 
31 #include "dec.h"
32 #include "ctu.h"
33 #include "data.h"
34 #include "refs.h"
35 #include "thread.h"
36 
37 #define TAB_MAX 32
38 
39 typedef struct Tab {
40  void **tab;
41  size_t size;
42 } Tab;
43 
44 typedef struct TabList {
46  int nb_tabs;
47 
48  int zero;
49  int realloc;
50 } TabList;
51 
52 #define TL_ADD(t, s) do { \
53  av_assert0(l->nb_tabs < TAB_MAX); \
54  l->tabs[l->nb_tabs].tab = (void**)&fc->tab.t; \
55  l->tabs[l->nb_tabs].size = sizeof(*fc->tab.t) * (s); \
56  l->nb_tabs++; \
57 } while (0)
58 
59 static void tl_init(TabList *l, const int zero, const int realloc)
60 {
61  l->nb_tabs = 0;
62  l->zero = zero;
63  l->realloc = realloc;
64 }
65 
66 static int tl_free(TabList *l)
67 {
68  for (int i = 0; i < l->nb_tabs; i++)
69  av_freep(l->tabs[i].tab);
70 
71  return 0;
72 }
73 
74 static int tl_create(TabList *l)
75 {
76  if (l->realloc) {
77  tl_free(l);
78 
79  for (int i = 0; i < l->nb_tabs; i++) {
80  Tab *t = l->tabs + i;
81  *t->tab = l->zero ? av_mallocz(t->size) : av_malloc(t->size);
82  if (!*t->tab)
83  return AVERROR(ENOMEM);
84  }
85  }
86  return 0;
87 }
88 
89 static int tl_zero(TabList *l)
90 {
91  if (l->zero) {
92  for (int i = 0; i < l->nb_tabs; i++) {
93  Tab *t = l->tabs + i;
94  memset(*t->tab, 0, t->size);
95  }
96  }
97  return 0;
98 }
99 
101 {
102  const VVCSPS *sps = fc->ps.sps;
103  const VVCPPS *pps = fc->ps.pps;
104  const int ctu_size = sps ? (1 << sps->ctb_log2_size_y << sps->ctb_log2_size_y) : 0;
105  const int ctu_count = pps ? pps->ctb_count : 0;
106  const int changed = fc->tab.sz.ctu_count != ctu_count || fc->tab.sz.ctu_size != ctu_size;
107 
108  tl_init(l, 0, changed);
109 
110  TL_ADD(cus, ctu_count);
111  TL_ADD(ctus, ctu_count);
112  TL_ADD(deblock, ctu_count);
113  TL_ADD(sao, ctu_count);
114  TL_ADD(alf, ctu_count);
115  TL_ADD(slice_idx, ctu_count);
116  TL_ADD(coeffs, ctu_count * ctu_size * VVC_MAX_SAMPLE_ARRAYS);
117 }
118 
120 {
121  const VVCPPS *pps = fc->ps.pps;
122  const int pic_size_in_min_cb = pps ? pps->min_cb_width * pps->min_cb_height : 0;
123  const int changed = fc->tab.sz.pic_size_in_min_cb != pic_size_in_min_cb;
124 
125  tl_init(l, 1, changed);
126 
127  TL_ADD(imf, pic_size_in_min_cb);
128  TL_ADD(imm, pic_size_in_min_cb);
129 
130  for (int i = LUMA; i <= CHROMA; i++)
131  TL_ADD(cb_width[i], pic_size_in_min_cb); //is_a0_available requires this
132 }
133 
135 {
136  const VVCPPS *pps = fc->ps.pps;
137  const int pic_size_in_min_cb = pps ? pps->min_cb_width * pps->min_cb_height : 0;
138  const int changed = fc->tab.sz.pic_size_in_min_cb != pic_size_in_min_cb;
139 
140  tl_init(l, 0, changed);
141 
142  TL_ADD(skip, pic_size_in_min_cb);
143  TL_ADD(imtf, pic_size_in_min_cb);
144  TL_ADD(ipm, pic_size_in_min_cb);
145 
146  for (int i = LUMA; i <= CHROMA; i++) {
147  TL_ADD(cqt_depth[i], pic_size_in_min_cb);
148  TL_ADD(cb_pos_x[i], pic_size_in_min_cb);
149  TL_ADD(cb_pos_y[i], pic_size_in_min_cb);
150  TL_ADD(cb_height[i], pic_size_in_min_cb);
151  TL_ADD(cp_mv[i], pic_size_in_min_cb * MAX_CONTROL_POINTS);
152  TL_ADD(cpm[i], pic_size_in_min_cb);
153  }
154  // For luma, qp can only change at the CU level, so the qp tab size is related to the CU.
155  TL_ADD(qp[LUMA], pic_size_in_min_cb);
156 }
157 
159 {
160  const VVCPPS *pps = fc->ps.pps;
161  const int pic_size_in_min_pu = pps ? pps->min_pu_width * pps->min_pu_height : 0;
162  const int changed = fc->tab.sz.pic_size_in_min_pu != pic_size_in_min_pu;
163 
164  tl_init(l, 1, changed);
165 
166  TL_ADD(iaf, pic_size_in_min_pu);
167 }
168 
170 {
171  const VVCPPS *pps = fc->ps.pps;
172  const int pic_size_in_min_pu = pps ? pps->min_pu_width * pps->min_pu_height : 0;
173  const int changed = fc->tab.sz.pic_size_in_min_pu != pic_size_in_min_pu;
174 
175  tl_init(l, 0, changed);
176 
177  TL_ADD(msf, pic_size_in_min_pu);
178  TL_ADD(mmi, pic_size_in_min_pu);
179  TL_ADD(mvf, pic_size_in_min_pu);
180 }
181 
183 {
184  const VVCPPS *pps = fc->ps.pps;
185  const int pic_size_in_min_tu = pps ? pps->min_tu_width * pps->min_tu_height : 0;
186  const int changed = fc->tab.sz.pic_size_in_min_tu != pic_size_in_min_tu;
187 
188  tl_init(l, 1, changed);
189 
190  TL_ADD(tu_joint_cbcr_residual_flag, pic_size_in_min_tu);
191 
192  for (int i = LUMA; i <= CHROMA; i++)
193  TL_ADD(pcmf[i], pic_size_in_min_tu);
194 
195  for (int i = 0; i < VVC_MAX_SAMPLE_ARRAYS; i++) {
196  TL_ADD(tu_coded_flag[i], pic_size_in_min_tu);
197 
198  for (int vertical = 0; vertical < 2; vertical++)
199  TL_ADD(bs[vertical][i], pic_size_in_min_tu);
200  }
201 }
202 
204 {
205  const VVCPPS *pps = fc->ps.pps;
206  const int pic_size_in_min_tu = pps ? pps->min_tu_width * pps->min_tu_height : 0;
207  const int changed = fc->tab.sz.pic_size_in_min_tu != pic_size_in_min_tu;
208 
209  tl_init(l, 0, changed);
210 
211  for (int i = LUMA; i <= CHROMA; i++) {
212  TL_ADD(tb_pos_x0[i], pic_size_in_min_tu);
213  TL_ADD(tb_pos_y0[i], pic_size_in_min_tu);
214  TL_ADD(tb_width[i], pic_size_in_min_tu);
215  TL_ADD(tb_height[i], pic_size_in_min_tu);
216  }
217 
218  for (int vertical = 0; vertical < 2; vertical++) {
219  TL_ADD(max_len_p[vertical], pic_size_in_min_tu);
220  TL_ADD(max_len_q[vertical], pic_size_in_min_tu);
221  }
222 
223  // For chroma, considering the joint CbCr, the QP tab size is related to the TU.
224  for (int i = CB; i < VVC_MAX_SAMPLE_ARRAYS; i++)
225  TL_ADD(qp[i], pic_size_in_min_tu);
226 }
227 
229 {
230  const VVCSPS *sps = fc->ps.sps;
231  const VVCPPS *pps = fc->ps.pps;
232  const int width = pps ? pps->width : 0;
233  const int height = pps ? pps->height : 0;
234  const int ctu_width = pps ? pps->ctb_width : 0;
235  const int ctu_height = pps ? pps->ctb_height : 0;
236  const int chroma_idc = sps ? sps->r->sps_chroma_format_idc : 0;
237  const int ps = sps ? sps->pixel_shift : 0;
238  const int c_end = chroma_idc ? VVC_MAX_SAMPLE_ARRAYS : 1;
239  const int changed = fc->tab.sz.chroma_format_idc != chroma_idc ||
240  fc->tab.sz.width != width || fc->tab.sz.height != height ||
241  fc->tab.sz.ctu_width != ctu_width || fc->tab.sz.ctu_height != ctu_height ||
242  fc->tab.sz.pixel_shift != ps;
243 
244  tl_init(l, 0, changed);
245 
246  for (int c_idx = 0; c_idx < c_end; c_idx++) {
247  const int w = width >> (sps ? sps->hshift[c_idx] : 0);
248  const int h = height >> (sps ? sps->vshift[c_idx] : 0);
249  TL_ADD(sao_pixel_buffer_h[c_idx], (w * 2 * ctu_height) << ps);
250  TL_ADD(sao_pixel_buffer_v[c_idx], (h * 2 * ctu_width) << ps);
251  }
252 
253  for (int c_idx = 0; c_idx < c_end; c_idx++) {
254  const int w = width >> (sps ? sps->hshift[c_idx] : 0);
255  const int h = height >> (sps ? sps->vshift[c_idx] : 0);
256  const int border_pixels = c_idx ? ALF_BORDER_CHROMA : ALF_BORDER_LUMA;
257  for (int i = 0; i < 2; i++) {
258  TL_ADD(alf_pixel_buffer_h[c_idx][i], (w * border_pixels * ctu_height) << ps);
259  TL_ADD(alf_pixel_buffer_v[c_idx][i], h * ALF_PADDING_SIZE * ctu_width);
260  }
261  }
262 }
263 
265 {
266  const VVCPPS *pps = fc->ps.pps;
267  const int w32 = pps ? AV_CEIL_RSHIFT(pps->width, 5) : 0;
268  const int h32 = pps ? AV_CEIL_RSHIFT(pps->height, 5) : 0;
269  const int changed = AV_CEIL_RSHIFT(fc->tab.sz.width, 5) != w32 ||
270  AV_CEIL_RSHIFT(fc->tab.sz.height, 5) != h32;
271 
272  tl_init(l, 1, changed);
273 
274  for (int i = LUMA; i <= CHROMA; i++)
275  TL_ADD(msm[i], w32 * h32);
276 }
277 
279 {
280  const VVCPPS *pps = fc->ps.pps;
281  const int w64 = pps ? AV_CEIL_RSHIFT(pps->width, 6) : 0;
282  const int h64 = pps ? AV_CEIL_RSHIFT(pps->height, 6) : 0;
283  const int changed = AV_CEIL_RSHIFT(fc->tab.sz.width, 6) != w64 ||
284  AV_CEIL_RSHIFT(fc->tab.sz.height, 6) != h64;
285 
286  tl_init(l, 1, changed);
287 
288  TL_ADD(ispmf, w64 * h64);
289 }
290 
292 {
293  const VVCSPS *sps = fc->ps.sps;
294  const VVCPPS *pps = fc->ps.pps;
295  const int ctu_height = pps ? pps->ctb_height : 0;
296  const int ctu_size = sps ? sps->ctb_size_y : 0;
297  const int ps = sps ? sps->pixel_shift : 0;
298  const int chroma_idc = sps ? sps->r->sps_chroma_format_idc : 0;
299  const int has_ibc = sps ? sps->r->sps_ibc_enabled_flag : 0;
300  const int changed = fc->tab.sz.chroma_format_idc != chroma_idc ||
301  fc->tab.sz.ctu_height != ctu_height ||
302  fc->tab.sz.ctu_size != ctu_size ||
303  fc->tab.sz.pixel_shift != ps;
304 
305  fc->tab.sz.ibc_buffer_width = ctu_size ? 2 * MAX_CTU_SIZE * MAX_CTU_SIZE / ctu_size : 0;
306 
307  tl_init(l, has_ibc, changed);
308 
309  for (int i = LUMA; i < VVC_MAX_SAMPLE_ARRAYS; i++) {
310  const int hs = sps ? sps->hshift[i] : 0;
311  const int vs = sps ? sps->vshift[i] : 0;
312  TL_ADD(ibc_vir_buf[i], fc->tab.sz.ibc_buffer_width * ctu_size * ctu_height << ps >> hs >> vs);
313  }
314 }
315 
316 typedef void (*tl_init_fn)(TabList *l, VVCFrameContext *fc);
317 
318 static int frame_context_for_each_tl(VVCFrameContext *fc, int (*unary_fn)(TabList *l))
319 {
320  const tl_init_fn init[] = {
329  msm_tl_init,
331  ibc_tl_init,
332  };
333 
334  for (int i = 0; i < FF_ARRAY_ELEMS(init); i++) {
335  TabList l;
336  int ret;
337 
338  init[i](&l, fc);
339  ret = unary_fn(&l);
340  if (ret < 0)
341  return ret;
342  }
343  return 0;
344 }
345 
347 {
348  if (fc->tab.cus) {
349  for (int i = 0; i < fc->tab.sz.ctu_count; i++)
350  ff_vvc_ctu_free_cus(fc->tab.cus + i);
351  }
352 }
353 
355 {
356  free_cus(fc);
358  ff_refstruct_pool_uninit(&fc->rpl_tab_pool);
359  ff_refstruct_pool_uninit(&fc->tab_dmvr_mvf_pool);
360 
361  memset(&fc->tab.sz, 0, sizeof(fc->tab.sz));
362 }
363 
365 {
366  const VVCSPS *sps = fc->ps.sps;
367  const VVCPPS *pps = fc->ps.pps;
368  const int ctu_count = pps->ctb_count;
369  const int pic_size_in_min_pu = pps->min_pu_width * pps->min_pu_height;
370  int ret;
371 
372  free_cus(fc);
373 
375  if (ret < 0)
376  return ret;
377 
378  // for error handling case, we may call free_cus before VVC_TASK_STAGE_INIT, so we need to set cus to 0 here
379  memset(fc->tab.cus, 0, sizeof(*fc->tab.cus) * ctu_count);
380 
381  memset(fc->tab.slice_idx, -1, sizeof(*fc->tab.slice_idx) * ctu_count);
382 
383  if (fc->tab.sz.ctu_count != ctu_count) {
384  ff_refstruct_pool_uninit(&fc->rpl_tab_pool);
385  fc->rpl_tab_pool = ff_refstruct_pool_alloc(ctu_count * sizeof(RefPicListTab), 0);
386  if (!fc->rpl_tab_pool)
387  return AVERROR(ENOMEM);
388  }
389 
390  if (fc->tab.sz.pic_size_in_min_pu != pic_size_in_min_pu) {
391  ff_refstruct_pool_uninit(&fc->tab_dmvr_mvf_pool);
392  fc->tab_dmvr_mvf_pool = ff_refstruct_pool_alloc(
393  pic_size_in_min_pu * sizeof(MvField), FF_REFSTRUCT_POOL_FLAG_ZERO_EVERY_TIME);
394  if (!fc->tab_dmvr_mvf_pool)
395  return AVERROR(ENOMEM);
396  }
397 
398  fc->tab.sz.ctu_count = pps->ctb_count;
399  fc->tab.sz.ctu_size = 1 << sps->ctb_log2_size_y << sps->ctb_log2_size_y;
400  fc->tab.sz.pic_size_in_min_cb = pps->min_cb_width * pps->min_cb_height;
401  fc->tab.sz.pic_size_in_min_pu = pic_size_in_min_pu;
402  fc->tab.sz.pic_size_in_min_tu = pps->min_tu_width * pps->min_tu_height;
403  fc->tab.sz.width = pps->width;
404  fc->tab.sz.height = pps->height;
405  fc->tab.sz.ctu_width = pps->ctb_width;
406  fc->tab.sz.ctu_height = pps->ctb_height;
407  fc->tab.sz.chroma_format_idc = sps->r->sps_chroma_format_idc;
408  fc->tab.sz.pixel_shift = sps->pixel_shift;
409 
410  return 0;
411 }
412 
414 {
416 }
417 
418 static int min_positive(const int idx, const int diff, const int min_diff)
419 {
420  return diff > 0 && (idx < 0 || diff < min_diff);
421 }
422 
423 static int max_negtive(const int idx, const int diff, const int max_diff)
424 {
425  return diff < 0 && (idx < 0 || diff > max_diff);
426 }
427 
428 typedef int (*smvd_find_fxn)(const int idx, const int diff, const int old_diff);
429 
430 static int8_t smvd_find(const VVCFrameContext *fc, const SliceContext *sc, int lx, smvd_find_fxn find)
431 {
432  const H266RawSliceHeader *rsh = sc->sh.r;
433  const RefPicList *rpl = sc->rpl + lx;
434  const int poc = fc->ref->poc;
435  int8_t idx = -1;
436  int old_diff = -1;
437  for (int i = 0; i < rsh->num_ref_idx_active[lx]; i++) {
438  if (!rpl->refs[i].is_lt) {
439  int diff = poc - rpl->refs[i].poc;
440  if (find(idx, diff, old_diff)) {
441  idx = i;
442  old_diff = diff;
443  }
444  }
445  }
446  return idx;
447 }
448 
449 static void smvd_ref_idx(const VVCFrameContext *fc, SliceContext *sc)
450 {
451  VVCSH *sh = &sc->sh;
452  if (IS_B(sh->r)) {
453  sh->ref_idx_sym[0] = smvd_find(fc, sc, 0, min_positive);
454  sh->ref_idx_sym[1] = smvd_find(fc, sc, 1, max_negtive);
455  if (sh->ref_idx_sym[0] == -1 || sh->ref_idx_sym[1] == -1) {
456  sh->ref_idx_sym[0] = smvd_find(fc, sc, 0, max_negtive);
457  sh->ref_idx_sym[1] = smvd_find(fc, sc, 1, min_positive);
458  }
459  }
460 }
461 
462 static void eps_free(SliceContext *slice)
463 {
464  av_freep(&slice->eps);
465  slice->nb_eps = 0;
466 }
467 
469 {
470  if (fc->slices) {
471  for (int i = 0; i < fc->nb_slices_allocated; i++) {
472  SliceContext *slice = fc->slices[i];
473  if (slice) {
474  ff_refstruct_unref(&slice->ref);
475  ff_refstruct_unref(&slice->sh.r);
476  eps_free(slice);
477  av_free(slice);
478  }
479  }
480  av_freep(&fc->slices);
481  }
482  fc->nb_slices_allocated = 0;
483  fc->nb_slices = 0;
484 }
485 
487 {
488  void *p;
489  const int size = (fc->nb_slices_allocated + 1) * 3 / 2;
490 
491  if (fc->nb_slices < fc->nb_slices_allocated)
492  return 0;
493 
494  p = av_realloc_array(fc->slices, size, sizeof(*fc->slices));
495  if (!p)
496  return AVERROR(ENOMEM);
497 
498  fc->slices = p;
499  for (int i = fc->nb_slices_allocated; i < size; i++) {
500  fc->slices[i] = av_mallocz(sizeof(*fc->slices[0]));
501  if (!fc->slices[i]) {
502  fc->nb_slices_allocated = i;
503  return AVERROR(ENOMEM);
504  }
505  fc->slices[i]->slice_idx = i;
506  }
507  fc->nb_slices_allocated = size;
508 
509  return 0;
510 }
511 
512 static int ep_init_cabac_decoder(SliceContext *sc, const int index,
513  const H2645NAL *nal, GetBitContext *gb, const CodedBitstreamUnit *unit)
514 {
515  const H266RawSlice *slice = unit->content_ref;
516  const H266RawSliceHeader *rsh = sc->sh.r;
517  EntryPoint *ep = sc->eps + index;
518  int size;
519  int ret;
520 
521  if (index < rsh->num_entry_points) {
522  int skipped = 0;
523  int64_t start = (gb->index >> 3);
524  int64_t end = start + rsh->sh_entry_point_offset_minus1[index] + 1;
525  while (skipped < nal->skipped_bytes && nal->skipped_bytes_pos[skipped] <= start + slice->header_size) {
526  skipped++;
527  }
528  while (skipped < nal->skipped_bytes && nal->skipped_bytes_pos[skipped] <= end + slice->header_size) {
529  end--;
530  skipped++;
531  }
532  size = end - start;
533  size = av_clip(size, 0, get_bits_left(gb) / 8);
534  } else {
535  size = get_bits_left(gb) / 8;
536  }
537  av_assert0(gb->buffer + get_bits_count(gb) / 8 + size <= gb->buffer_end);
538  ret = ff_init_cabac_decoder (&ep->cc, gb->buffer + get_bits_count(gb) / 8, size);
539  if (ret < 0)
540  return ret;
541  skip_bits(gb, size * 8);
542  return 0;
543 }
544 
546  VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit)
547 {
548  const VVCSH *sh = &sc->sh;
549  const H266RawSlice *slice = unit->content_ref;
550  int nb_eps = sh->r->num_entry_points + 1;
551  int ctu_addr = 0;
552  GetBitContext gb;
553  int ret;
554 
555  if (sc->nb_eps != nb_eps) {
556  eps_free(sc);
557  sc->eps = av_calloc(nb_eps, sizeof(*sc->eps));
558  if (!sc->eps)
559  return AVERROR(ENOMEM);
560  sc->nb_eps = nb_eps;
561  }
562 
563  ret = init_get_bits8(&gb, slice->data, slice->data_size);
564  if (ret < 0)
565  return ret;
566  for (int i = 0; i < sc->nb_eps; i++)
567  {
568  EntryPoint *ep = sc->eps + i;
569 
570  ep->ctu_start = ctu_addr;
571  ep->ctu_end = (i + 1 == sc->nb_eps ? sh->num_ctus_in_curr_slice : sh->entry_point_start_ctu[i]);
572 
573  for (int j = ep->ctu_start; j < ep->ctu_end; j++) {
574  const int rs = sc->sh.ctb_addr_in_curr_slice[j];
575  fc->tab.slice_idx[rs] = sc->slice_idx;
576  }
577 
578  ret = ep_init_cabac_decoder(sc, i, nal, &gb, unit);
579  if (ret < 0)
580  return ret;
581 
582  if (i + 1 < sc->nb_eps)
583  ctu_addr = sh->entry_point_start_ctu[i];
584  }
585 
586  return 0;
587 }
588 
590 {
591  const int size = s->nb_fcs;
592  const int idx = (fc - s->fcs + delta + size) % size;
593  return s->fcs + idx;
594 }
595 
596 static int ref_frame(VVCFrame *dst, const VVCFrame *src)
597 {
598  int ret;
599 
600  ret = av_frame_ref(dst->frame, src->frame);
601  if (ret < 0)
602  return ret;
603 
604  ff_refstruct_replace(&dst->sps, src->sps);
605  ff_refstruct_replace(&dst->pps, src->pps);
606 
607  ff_refstruct_replace(&dst->progress, src->progress);
608 
609  ff_refstruct_replace(&dst->tab_dmvr_mvf, src->tab_dmvr_mvf);
610 
611  ff_refstruct_replace(&dst->rpl_tab, src->rpl_tab);
612  ff_refstruct_replace(&dst->rpl, src->rpl);
613  dst->nb_rpl_elems = src->nb_rpl_elems;
614 
615  dst->poc = src->poc;
616  dst->ctb_count = src->ctb_count;
617 
618  dst->scaling_win = src->scaling_win;
619  dst->ref_width = src->ref_width;
620  dst->ref_height = src->ref_height;
621 
622  dst->flags = src->flags;
623  dst->sequence = src->sequence;
624 
625  return 0;
626 }
627 
629 {
630  slices_free(fc);
631 
632  ff_refstruct_pool_uninit(&fc->tu_pool);
633  ff_refstruct_pool_uninit(&fc->cu_pool);
634 
635  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
636  ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
637  av_frame_free(&fc->DPB[i].frame);
638  }
639 
642  av_frame_free(&fc->output_frame);
643  ff_vvc_frame_ps_free(&fc->ps);
644 }
645 
647 {
648 
649  fc->log_ctx = avctx;
650 
651  fc->output_frame = av_frame_alloc();
652  if (!fc->output_frame)
653  return AVERROR(ENOMEM);
654 
655  for (int j = 0; j < FF_ARRAY_ELEMS(fc->DPB); j++) {
656  fc->DPB[j].frame = av_frame_alloc();
657  if (!fc->DPB[j].frame)
658  return AVERROR(ENOMEM);
659  }
660  fc->cu_pool = ff_refstruct_pool_alloc(sizeof(CodingUnit), 0);
661  if (!fc->cu_pool)
662  return AVERROR(ENOMEM);
663 
664  fc->tu_pool = ff_refstruct_pool_alloc(sizeof(TransformUnit), 0);
665  if (!fc->tu_pool)
666  return AVERROR(ENOMEM);
667 
668  return 0;
669 }
670 
672 {
673  int ret;
674 
675  fc->ref = NULL;
676 
677  // copy refs from the last frame
678  if (s->nb_frames && s->nb_fcs > 1) {
679  VVCFrameContext *prev = get_frame_context(s, fc, -1);
680  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
681  ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
682  if (prev->DPB[i].frame->buf[0]) {
683  ret = ref_frame(&fc->DPB[i], &prev->DPB[i]);
684  if (ret < 0)
685  return ret;
686  }
687  }
688  }
689 
690  if (IS_IDR(s)) {
691  s->seq_decode = (s->seq_decode + 1) & 0xff;
693  }
694 
695  ret = pic_arrays_init(s, fc);
696  if (ret < 0)
697  return ret;
698  ff_vvc_dsp_init(&fc->vvcdsp, fc->ps.sps->bit_depth);
699  ff_videodsp_init(&fc->vdsp, fc->ps.sps->bit_depth);
700  return 0;
701 }
702 
704 {
705  const VVCPH *ph = &fc->ps.ph;
706  const H266RawSliceHeader *rsh = sc->sh.r;
707  int ret;
708 
709  // 8.3.1 Decoding process for picture order count
710  if (!s->temporal_id && !ph->r->ph_non_ref_pic_flag && !(IS_RASL(s) || IS_RADL(s)))
711  s->poc_tid0 = ph->poc;
712 
713  if ((ret = ff_vvc_set_new_ref(s, fc, &fc->frame)) < 0)
714  goto fail;
715 
716  if (!IS_IDR(s))
718 
719  av_frame_unref(fc->output_frame);
720 
721  if ((ret = ff_vvc_output_frame(s, fc, fc->output_frame,rsh->sh_no_output_of_prior_pics_flag, 0)) < 0)
722  goto fail;
723 
724  if ((ret = ff_vvc_frame_rpl(s, fc, sc)) < 0)
725  goto fail;
726 
727  if ((ret = ff_vvc_frame_thread_init(fc)) < 0)
728  goto fail;
729  return 0;
730 fail:
731  if (fc->ref)
732  ff_vvc_unref_frame(fc, fc->ref, ~0);
733  fc->ref = NULL;
734  return ret;
735 }
736 
738  const CodedBitstreamUnit *unit, const int is_first_slice)
739 {
740  VVCSH *sh = &sc->sh;
741  int ret;
742 
743  ret = ff_vvc_decode_sh(sh, &fc->ps, unit);
744  if (ret < 0)
745  return ret;
746 
747  ff_refstruct_replace(&sc->ref, unit->content_ref);
748 
749  if (is_first_slice) {
750  ret = frame_start(s, fc, sc);
751  if (ret < 0)
752  return ret;
753  } else if (fc->ref) {
754  if (!IS_I(sh->r)) {
755  ret = ff_vvc_slice_rpl(s, fc, sc);
756  if (ret < 0) {
757  av_log(fc->log_ctx, AV_LOG_WARNING,
758  "Error constructing the reference lists for the current slice.\n");
759  return ret;
760  }
761  }
762  } else {
763  av_log(fc->log_ctx, AV_LOG_ERROR, "First slice in a frame missing.\n");
764  return ret;
765  }
766 
767  if (!IS_I(sh->r))
768  smvd_ref_idx(fc, sc);
769 
770  return 0;
771 }
772 
774 {
775  AVCodecContext *c = s->avctx;
776  const VVCSPS *sps = fc->ps.sps;
777  const VVCPPS *pps = fc->ps.pps;
778 
779  c->pix_fmt = sps->pix_fmt;
780  c->coded_width = pps->width;
781  c->coded_height = pps->height;
782  c->width = pps->width - ((pps->r->pps_conf_win_left_offset + pps->r->pps_conf_win_right_offset) << sps->hshift[CHROMA]);
783  c->height = pps->height - ((pps->r->pps_conf_win_top_offset + pps->r->pps_conf_win_bottom_offset) << sps->vshift[CHROMA]);
784  c->has_b_frames = sps->r->sps_dpb_params.dpb_max_num_reorder_pics[sps->r->sps_max_sublayers_minus1];
785 }
786 
788 {
789  int ret = ff_vvc_decode_frame_ps(&fc->ps, s);
790  if (ret < 0)
791  return ret;
792 
794  if (ret < 0)
795  return ret;
796 
798  return ret;
799 }
800 
801 static int decode_slice(VVCContext *s, VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit)
802 {
803  int ret;
804  SliceContext *sc;
805  const int is_first_slice = !fc->nb_slices;
806 
807  ret = slices_realloc(fc);
808  if (ret < 0)
809  return ret;
810 
811  sc = fc->slices[fc->nb_slices];
812 
813  s->vcl_unit_type = nal->type;
814  if (is_first_slice) {
815  ret = frame_setup(fc, s);
816  if (ret < 0)
817  return ret;
818  }
819 
820  ret = slice_start(sc, s, fc, unit, is_first_slice);
821  if (ret < 0)
822  return ret;
823 
824  ret = slice_init_entry_points(sc, fc, nal, unit);
825  if (ret < 0)
826  return ret;
827  fc->nb_slices++;
828 
829  return 0;
830 }
831 
833 {
834  int ret;
835 
836  s->temporal_id = nal->temporal_id;
837 
838  if (nal->nuh_layer_id > 0) {
840  "Decoding of multilayer bitstreams");
841  return AVERROR_PATCHWELCOME;
842  }
843 
844  switch (unit->type) {
845  case VVC_VPS_NUT:
846  case VVC_SPS_NUT:
847  case VVC_PPS_NUT:
848  /* vps, sps, sps cached by s->cbc */
849  break;
850  case VVC_TRAIL_NUT:
851  case VVC_STSA_NUT:
852  case VVC_RADL_NUT:
853  case VVC_RASL_NUT:
854  case VVC_IDR_W_RADL:
855  case VVC_IDR_N_LP:
856  case VVC_CRA_NUT:
857  case VVC_GDR_NUT:
858  ret = decode_slice(s, fc, nal, unit);
859  if (ret < 0)
860  return ret;
861  break;
862  case VVC_PREFIX_APS_NUT:
863  case VVC_SUFFIX_APS_NUT:
864  ret = ff_vvc_decode_aps(&s->ps, unit);
865  if (ret < 0)
866  return ret;
867  break;
868  }
869 
870  return 0;
871 }
872 
874 {
875  const CodedBitstreamH266Context *h266 = s->cbc->priv_data;
876  CodedBitstreamFragment *frame = &s->current_frame;
877  int ret = 0;
878  s->last_eos = s->eos;
879  s->eos = 0;
880 
882  ret = ff_cbs_read_packet(s->cbc, frame, avpkt);
883  if (ret < 0) {
884  av_log(s->avctx, AV_LOG_ERROR, "Failed to read packet.\n");
885  return ret;
886  }
887  /* decode the NAL units */
888  for (int i = 0; i < frame->nb_units; i++) {
889  const H2645NAL *nal = h266->common.read_packet.nals + i;
890  const CodedBitstreamUnit *unit = frame->units + i;
891 
892  if (unit->type == VVC_EOB_NUT || unit->type == VVC_EOS_NUT) {
893  s->last_eos = 1;
894  } else {
895  ret = decode_nal_unit(s, fc, nal, unit);
896  if (ret < 0) {
897  av_log(s->avctx, AV_LOG_WARNING,
898  "Error parsing NAL unit #%d.\n", i);
899  goto fail;
900  }
901  }
902  }
903  return 0;
904 
905 fail:
906  if (fc->ref)
908  return ret;
909 }
910 
911 static int set_output_format(const VVCContext *s, const AVFrame *output)
912 {
913  AVCodecContext *c = s->avctx;
914  int ret;
915 
916  if (output->width != c->width || output->height != c->height) {
917  if ((ret = ff_set_dimensions(c, output->width, output->height)) < 0)
918  return ret;
919  }
920  c->pix_fmt = output->format;
921  return 0;
922 }
923 
924 static int wait_delayed_frame(VVCContext *s, AVFrame *output, int *got_output)
925 {
926  VVCFrameContext *delayed = get_frame_context(s, s->fcs, s->nb_frames - s->nb_delayed);
927  int ret = ff_vvc_frame_wait(s, delayed);
928 
929  if (!ret && delayed->output_frame->buf[0] && output) {
932  if (!ret)
933  *got_output = 1;
934  }
935  s->nb_delayed--;
936 
937  return ret;
938 }
939 
940 static int submit_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *output, int *got_output)
941 {
942  int ret = ff_vvc_frame_submit(s, fc);
943 
944  if (ret < 0) {
946  return ret;
947  }
948 
949  s->nb_frames++;
950  s->nb_delayed++;
951 
952  if (s->nb_delayed >= s->nb_fcs) {
953  if ((ret = wait_delayed_frame(s, output, got_output)) < 0)
954  return ret;
955  }
956  return 0;
957 }
958 
959 static int get_decoded_frame(VVCContext *s, AVFrame *output, int *got_output)
960 {
961  int ret;
962  while (s->nb_delayed) {
963  if ((ret = wait_delayed_frame(s, output, got_output)) < 0)
964  return ret;
965  if (*got_output)
966  return 0;
967  }
968  if (s->nb_frames) {
969  //we still have frames cached in dpb.
970  VVCFrameContext *last = get_frame_context(s, s->fcs, s->nb_frames - 1);
971 
972  ret = ff_vvc_output_frame(s, last, output, 0, 1);
973  if (ret < 0)
974  return ret;
975  if (ret) {
976  *got_output = ret;
977  if ((ret = set_output_format(s, output)) < 0)
978  return ret;
979  }
980  }
981  return 0;
982 }
983 
985  int *got_output, AVPacket *avpkt)
986 {
987  VVCContext *s = avctx->priv_data;
989  int ret;
990 
991  if (!avpkt->size)
992  return get_decoded_frame(s, output, got_output);
993 
994  fc = get_frame_context(s, s->fcs, s->nb_frames);
995 
996  fc->nb_slices = 0;
997  fc->decode_order = s->nb_frames;
998 
999  ret = decode_nal_units(s, fc, avpkt);
1000  if (ret < 0)
1001  return ret;
1002 
1003  if (!fc->ft)
1004  return avpkt->size;
1005 
1006  ret = submit_frame(s, fc, output, got_output);
1007  if (ret < 0)
1008  return ret;
1009 
1010  return avpkt->size;
1011 }
1012 
1014 {
1015  VVCContext *s = avctx->priv_data;
1016  int got_output = 0;
1017 
1018  while (s->nb_delayed)
1019  wait_delayed_frame(s, NULL, &got_output);
1020 
1021  if (s->fcs) {
1022  VVCFrameContext *last = get_frame_context(s, s->fcs, s->nb_frames - 1);
1023  ff_vvc_flush_dpb(last);
1024  }
1025 
1026  s->ps.sps_id_used = 0;
1027 
1028  s->eos = 1;
1029 }
1030 
1032 {
1033  VVCContext *s = avctx->priv_data;
1034 
1035  ff_cbs_fragment_free(&s->current_frame);
1036  vvc_decode_flush(avctx);
1037  ff_vvc_executor_free(&s->executor);
1038  if (s->fcs) {
1039  for (int i = 0; i < s->nb_fcs; i++)
1040  frame_context_free(s->fcs + i);
1041  av_free(s->fcs);
1042  }
1043  ff_vvc_ps_uninit(&s->ps);
1044  ff_cbs_close(&s->cbc);
1045 
1046  return 0;
1047 }
1048 
1050 {
1051  memset(&ff_vvc_default_scale_m, 16, sizeof(ff_vvc_default_scale_m));
1052 }
1053 
1054 #define VVC_MAX_DELAYED_FRAMES 16
1056 {
1057  VVCContext *s = avctx->priv_data;
1058  static AVOnce init_static_once = AV_ONCE_INIT;
1059  const int cpu_count = av_cpu_count();
1060  const int delayed = FFMIN(cpu_count, VVC_MAX_DELAYED_FRAMES);
1061  int thread_count = avctx->thread_count ? avctx->thread_count : delayed;
1062  int ret;
1063 
1064  s->avctx = avctx;
1065 
1066  ret = ff_cbs_init(&s->cbc, AV_CODEC_ID_VVC, avctx);
1067  if (ret)
1068  return ret;
1069 
1070  if (avctx->extradata_size > 0 && avctx->extradata) {
1071  ret = ff_cbs_read_extradata_from_codec(s->cbc, &s->current_frame, avctx);
1072  if (ret < 0)
1073  return ret;
1074  }
1075 
1076  s->nb_fcs = (avctx->flags & AV_CODEC_FLAG_LOW_DELAY) ? 1 : delayed;
1077  s->fcs = av_calloc(s->nb_fcs, sizeof(*s->fcs));
1078  if (!s->fcs)
1079  return AVERROR(ENOMEM);
1080 
1081  for (int i = 0; i < s->nb_fcs; i++) {
1082  VVCFrameContext *fc = s->fcs + i;
1083  ret = frame_context_init(fc, avctx);
1084  if (ret < 0)
1085  return ret;
1086  }
1087 
1088  if (thread_count == 1)
1089  thread_count = 0;
1090  s->executor = ff_vvc_executor_alloc(s, thread_count);
1091  if (!s->executor)
1092  return AVERROR(ENOMEM);
1093 
1094  s->eos = 1;
1096  ff_thread_once(&init_static_once, init_default_scale_m);
1097 
1098  return 0;
1099 }
1100 
1102  .p.name = "vvc",
1103  .p.long_name = NULL_IF_CONFIG_SMALL("VVC (Versatile Video Coding)"),
1104  .p.type = AVMEDIA_TYPE_VIDEO,
1105  .p.id = AV_CODEC_ID_VVC,
1106  .priv_data_size = sizeof(VVCContext),
1107  .init = vvc_decode_init,
1108  .close = vvc_decode_free,
1110  .flush = vvc_decode_flush,
1115  .p.profiles = NULL_IF_CONFIG_SMALL(ff_vvc_profiles),
1116 };
VVC_RADL_NUT
@ VVC_RADL_NUT
Definition: vvc.h:31
VVC_RASL_NUT
@ VVC_RASL_NUT
Definition: vvc.h:32
VVC_GDR_NUT
@ VVC_GDR_NUT
Definition: vvc.h:39
VVC_STSA_NUT
@ VVC_STSA_NUT
Definition: vvc.h:30
VVCSPS
Definition: ps.h:58
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
ALF_BORDER_LUMA
#define ALF_BORDER_LUMA
Definition: ctu.h:76
CodedBitstreamUnit::content_ref
void * content_ref
If content is reference counted, a RefStruct reference backing content.
Definition: cbs.h:112
slices_realloc
static int slices_realloc(VVCFrameContext *fc)
Definition: dec.c:486
VVCSH::num_ctus_in_curr_slice
uint32_t num_ctus_in_curr_slice
NumCtusInCurrSlice.
Definition: ps.h:242
VVCPH
Definition: ps.h:147
VVCFrameContext::output_frame
struct AVFrame * output_frame
Definition: dec.h:122
decode_slice
static int decode_slice(VVCContext *s, VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit)
Definition: dec.c:801
VVCPPS
Definition: ps.h:92
av_clip
#define av_clip
Definition: common.h:100
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:42
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:695
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
LUMA
#define LUMA
Definition: filter.c:31
cpu_count
static atomic_int cpu_count
Definition: cpu.c:53
VVCFrame::pps
const VVCPPS * pps
RefStruct reference.
Definition: dec.h:75
ff_vvc_decode_frame_ps
int ff_vvc_decode_frame_ps(VVCFrameParamSets *fps, struct VVCContext *s)
Definition: ps.c:927
VVCSH::entry_point_start_ctu
uint32_t entry_point_start_ctu[VVC_MAX_ENTRY_POINTS]
entry point start in ctu_addr
Definition: ps.h:264
ff_refstruct_pool_alloc
FFRefStructPool * ff_refstruct_pool_alloc(size_t size, unsigned flags)
Equivalent to ff_refstruct_pool_alloc(size, flags, NULL, NULL, NULL, NULL, NULL)
Definition: refstruct.c:335
CB
#define CB
Definition: filter.c:32
set_output_format
static int set_output_format(const VVCContext *s, const AVFrame *output)
Definition: dec.c:911
ff_cbs_fragment_free
av_cold void ff_cbs_fragment_free(CodedBitstreamFragment *frag)
Free the units array of a fragment in addition to what ff_cbs_fragment_reset does.
Definition: cbs.c:186
thread.h
TL_ADD
#define TL_ADD(t, s)
Definition: dec.c:52
ff_vvc_report_frame_finished
void ff_vvc_report_frame_finished(VVCFrame *frame)
Definition: refs.c:545
CodingUnit
Definition: hevcdec.h:285
int64_t
long long int64_t
Definition: coverity.c:34
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
H266RawSliceHeader::sh_no_output_of_prior_pics_flag
uint8_t sh_no_output_of_prior_pics_flag
Definition: cbs_h266.h:779
VVCFrameContext::DPB
VVCFrame DPB[VVC_MAX_DPB_SIZE+1]
Definition: dec.h:119
pixel_buffer_nz_tl_init
static void pixel_buffer_nz_tl_init(TabList *l, VVCFrameContext *fc)
Definition: dec.c:228
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:266
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
data.h
ph
static int FUNC() ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
Definition: cbs_h266_syntax_template.c:3032
H2645NAL::nuh_layer_id
int nuh_layer_id
Definition: h2645_parse.h:67
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
w
uint8_t w
Definition: llviddspenc.c:38
ff_cbs_fragment_reset
void ff_cbs_fragment_reset(CodedBitstreamFragment *frag)
Free the units contained in a fragment as well as the fragment's own data buffer, but not the units a...
Definition: cbs.c:172
VVCSH::r
const H266RawSliceHeader * r
RefStruct reference.
Definition: ps.h:238
FFCodec
Definition: codec_internal.h:126
IS_RADL
#define IS_RADL(s)
Definition: ps.h:36
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
ff_vvc_slice_rpl
int ff_vvc_slice_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc)
Definition: refs.c:462
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:587
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:94
H2645NAL::temporal_id
int temporal_id
HEVC only, nuh_temporal_id_plus_1 - 1.
Definition: h2645_parse.h:62
RefPicList
Definition: hevcdec.h:190
min_tu_tl_init
static void min_tu_tl_init(TabList *l, VVCFrameContext *fc)
Definition: dec.c:182
CodedBitstreamUnit
Coded bitstream unit structure.
Definition: cbs.h:70
ff_cbs_close
av_cold void ff_cbs_close(CodedBitstreamContext **ctx_ptr)
Close a context and free all internal state.
Definition: cbs.c:142
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
smvd_find
static int8_t smvd_find(const VVCFrameContext *fc, const SliceContext *sc, int lx, smvd_find_fxn find)
Definition: dec.c:430
frame_setup
static int frame_setup(VVCFrameContext *fc, VVCContext *s)
Definition: dec.c:787
skip_bits
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:381
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:130
ref_frame
static int ref_frame(VVCFrame *dst, const VVCFrame *src)
Definition: dec.c:596
fail
#define fail()
Definition: checkasm.h:188
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1587
ff_refstruct_pool_uninit
static void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition: refstruct.h:292
VVCFrame::rpl
RefPicListTab * rpl
RefStruct reference.
Definition: dec.h:78
tl_init_fn
void(* tl_init_fn)(TabList *l, VVCFrameContext *fc)
Definition: dec.c:316
get_frame_context
static VVCFrameContext * get_frame_context(const VVCContext *s, const VVCFrameContext *fc, const int delta)
Definition: dec.c:589
VVCFrame::ref_height
int ref_height
CurrPicScalWinHeightL.
Definition: dec.h:89
IS_B
#define IS_B(rsh)
Definition: ps.h:40
GetBitContext
Definition: get_bits.h:108
ff_vvc_decode_sh
int ff_vvc_decode_sh(VVCSH *sh, const VVCFrameParamSets *fps, const CodedBitstreamUnit *unit)
Definition: ps.c:1334
export_frame_params
static void export_frame_params(VVCContext *s, const VVCFrameContext *fc)
Definition: dec.c:773
min_cb_tl_init
static void min_cb_tl_init(TabList *l, VVCFrameContext *fc)
Definition: dec.c:119
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:502
ff_videodsp_init
av_cold void ff_videodsp_init(VideoDSPContext *ctx, int bpc)
Definition: videodsp.c:39
AV_CODEC_FLAG_LOW_DELAY
#define AV_CODEC_FLAG_LOW_DELAY
Force low delay.
Definition: avcodec.h:334
SliceContext::rpl
RefPicList * rpl
Definition: dec.h:111
eps_free
static void eps_free(SliceContext *slice)
Definition: dec.c:462
VVC_IDR_W_RADL
@ VVC_IDR_W_RADL
Definition: vvc.h:36
frame_context_setup
static int frame_context_setup(VVCFrameContext *fc, VVCContext *s)
Definition: dec.c:671
vvc_decode_free
static av_cold int vvc_decode_free(AVCodecContext *avctx)
Definition: dec.c:1031
ff_vvc_decoder
const FFCodec ff_vvc_decoder
Definition: dec.c:1101
refstruct.h
ff_vvc_frame_ps_free
void ff_vvc_frame_ps_free(VVCFrameParamSets *fps)
Definition: ps.c:946
VVC_EOS_NUT
@ VVC_EOS_NUT
Definition: vvc.h:50
ff_vvc_frame_submit
int ff_vvc_frame_submit(VVCContext *s, VVCFrameContext *fc)
Definition: thread.c:804
GDR_SET_RECOVERED
#define GDR_SET_RECOVERED(s)
Definition: ps.h:44
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:148
VVCFrame::scaling_win
VVCWindow scaling_win
pps_scaling_win_left_offset * SubWithC, pps_scaling_win_right_offset * SubWithC, pps_scaling_win_top_...
Definition: dec.h:86
H266RawSliceHeader::num_ref_idx_active
uint8_t num_ref_idx_active[2]
NumRefIdxActive[].
Definition: cbs_h266.h:837
frame_context_init
static av_cold int frame_context_init(VVCFrameContext *fc, AVCodecContext *avctx)
Definition: dec.c:646
ff_thread_once
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:205
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
H266RawSlice::data
uint8_t * data
Definition: cbs_h266.h:844
free_cus
static void free_cus(VVCFrameContext *fc)
Definition: dec.c:346
AV_CODEC_CAP_EXPERIMENTAL
#define AV_CODEC_CAP_EXPERIMENTAL
Codec is experimental and is thus avoided in favor of non experimental encoders.
Definition: codec.h:102
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:545
slice_init_entry_points
static int slice_init_entry_points(SliceContext *sc, VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit)
Definition: dec.c:545
RefPicList::refs
VVCRefPic refs[VVC_MAX_REF_ENTRIES]
Definition: dec.h:56
VVCFrame::flags
uint8_t flags
A combination of VVC_FRAME_FLAG_*.
Definition: dec.h:103
VVC_MAX_DELAYED_FRAMES
#define VVC_MAX_DELAYED_FRAMES
Definition: dec.c:1054
ff_vvc_unref_frame
void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags)
Definition: refs.c:46
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:524
ff_vvc_frame_wait
int ff_vvc_frame_wait(VVCContext *s, VVCFrameContext *fc)
Definition: thread.c:826
CodedBitstreamFragment
Coded bitstream fragment structure, combining one or more units.
Definition: cbs.h:122
ff_vvc_executor_free
void ff_vvc_executor_free(AVExecutor **e)
Definition: thread.c:694
width
#define width
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:286
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:60
SliceContext::slice_idx
int slice_idx
Definition: dec.h:107
av_realloc_array
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Definition: mem.c:217
tl_create
static int tl_create(TabList *l)
Definition: dec.c:74
AV_CODEC_CAP_OTHER_THREADS
#define AV_CODEC_CAP_OTHER_THREADS
Codec supports multithreading through a method other than slice- or frame-level multithreading.
Definition: codec.h:124
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
min_tu_nz_tl_init
static void min_tu_nz_tl_init(TabList *l, VVCFrameContext *fc)
Definition: dec.c:203
VVCSH
Definition: ps.h:237
ff_vvc_clear_refs
void ff_vvc_clear_refs(VVCFrameContext *fc)
Definition: refs.c:79
decode.h
IS_IDR
#define IS_IDR(s)
Definition: hevcdec.h:76
H2645NAL::skipped_bytes_pos
int * skipped_bytes_pos
Definition: h2645_parse.h:71
TabList::tabs
Tab tabs[TAB_MAX]
Definition: dec.c:45
ispmf_tl_init
static void ispmf_tl_init(TabList *l, VVCFrameContext *fc)
Definition: dec.c:278
ff_vvc_default_scale_m
uint8_t ff_vvc_default_scale_m[64 *64]
Definition: data.c:1641
H2645NAL::type
int type
NAL unit type.
Definition: h2645_parse.h:52
decode_nal_unit
static int decode_nal_unit(VVCContext *s, VVCFrameContext *fc, const H2645NAL *nal, const CodedBitstreamUnit *unit)
Definition: dec.c:832
slices_free
static void slices_free(VVCFrameContext *fc)
Definition: dec.c:468
GetBitContext::buffer
const uint8_t * buffer
Definition: get_bits.h:109
AV_ONCE_INIT
#define AV_ONCE_INIT
Definition: thread.h:203
smvd_ref_idx
static void smvd_ref_idx(const VVCFrameContext *fc, SliceContext *sc)
Definition: dec.c:449
NULL
#define NULL
Definition: coverity.c:32
ff_vvc_frame_thread_init
int ff_vvc_frame_thread_init(VVCFrameContext *fc)
Definition: thread.c:739
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
TabList
Definition: dec.c:44
VVCSH::ref_idx_sym
int8_t ref_idx_sym[2]
RefIdxSymL0, RefIdxSymL1.
Definition: ps.h:247
SliceContext::eps
struct EntryPoint * eps
Definition: dec.h:109
profiles.h
CodedBitstreamH266Context::common
CodedBitstreamH2645Context common
Definition: cbs_h266.h:858
CodedBitstreamH2645Context::read_packet
H2645Packet read_packet
Definition: cbs_h2645.h:32
RefPicListTab
Definition: hevcdec.h:197
MAX_CTU_SIZE
#define MAX_CTU_SIZE
Definition: ctu.h:31
VVCRefPic::is_lt
int is_lt
Definition: dec.h:48
smvd_find_fxn
int(* smvd_find_fxn)(const int idx, const int diff, const int old_diff)
Definition: dec.c:428
submit_frame
static int submit_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *output, int *got_output)
Definition: dec.c:940
AVOnce
#define AVOnce
Definition: thread.h:202
index
int index
Definition: gxfenc.c:90
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
IS_RASL
#define IS_RASL(s)
Definition: ps.h:35
TransformUnit
Definition: hevcdec.h:328
VVCFrame::sequence
uint16_t sequence
A sequence counter, so that old frames are output first after a POC reset.
Definition: dec.h:99
SliceContext
Definition: mss12.h:70
av_cpu_count
int av_cpu_count(void)
Definition: cpu.c:209
ff_vvc_flush_dpb
void ff_vvc_flush_dpb(VVCFrameContext *fc)
Definition: refs.c:86
H266RawSliceHeader::sh_entry_point_offset_minus1
uint32_t sh_entry_point_offset_minus1[VVC_MAX_ENTRY_POINTS]
Definition: cbs_h266.h:832
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:366
TabList::nb_tabs
int nb_tabs
Definition: dec.c:46
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
ibc_tl_init
static void ibc_tl_init(TabList *l, VVCFrameContext *fc)
Definition: dec.c:291
AVPacket::size
int size
Definition: packet.h:534
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
Tab
Definition: dec.c:39
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:386
codec_internal.h
VVC_VPS_NUT
@ VVC_VPS_NUT
Definition: vvc.h:43
ALF_PADDING_SIZE
#define ALF_PADDING_SIZE
Definition: ctu.h:73
cpu.h
pic_arrays_init
static int pic_arrays_init(VVCContext *s, VVCFrameContext *fc)
Definition: dec.c:364
FF_CODEC_CAP_EXPORTS_CROPPING
#define FF_CODEC_CAP_EXPORTS_CROPPING
The decoder sets the cropping fields in the output frames manually.
Definition: codec_internal.h:60
ff_vvc_frame_thread_free
void ff_vvc_frame_thread_free(VVCFrameContext *fc)
Definition: thread.c:699
size
int size
Definition: twinvq_data.h:10344
EntryPoint::cc
CABACContext cc
Definition: ctu.h:357
EntryPoint::ctu_end
int ctu_end
Definition: ctu.h:360
get_decoded_frame
static int get_decoded_frame(VVCContext *s, AVFrame *output, int *got_output)
Definition: dec.c:959
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.
H2645NAL
Definition: h2645_parse.h:34
VVCRefPic::poc
int poc
Definition: dec.h:47
GetBitContext::index
int index
Definition: get_bits.h:110
min_cb_nz_tl_init
static void min_cb_nz_tl_init(TabList *l, VVCFrameContext *fc)
Definition: dec.c:134
SliceContext::ref
void * ref
RefStruct reference, backing slice data.
Definition: dec.h:112
MvField
Definition: hevcdec.h:303
pic_arrays_free
static void pic_arrays_free(VVCFrameContext *fc)
Definition: dec.c:354
refs.h
diff
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
Definition: vf_paletteuse.c:164
VVCFrame
Definition: dec.h:71
ff_vvc_dsp_init
void ff_vvc_dsp_init(VVCDSPContext *vvcdsp, int bit_depth)
Definition: dsp.c:77
height
#define height
VVCFrame::tab_dmvr_mvf
struct MvField * tab_dmvr_mvf
RefStruct reference.
Definition: dec.h:76
CodedBitstreamH266Context
Definition: cbs_h266.h:856
AV_CODEC_ID_VVC
@ AV_CODEC_ID_VVC
Definition: codec_id.h:250
MAX_CONTROL_POINTS
#define MAX_CONTROL_POINTS
Definition: ctu.h:64
VVCSH::ctb_addr_in_curr_slice
const uint32_t * ctb_addr_in_curr_slice
CtbAddrInCurrSlice.
Definition: ps.h:243
VVC_TRAIL_NUT
@ VVC_TRAIL_NUT
Definition: vvc.h:29
tl_free
static int tl_free(TabList *l)
Definition: dec.c:66
VVC_SPS_NUT
@ VVC_SPS_NUT
Definition: vvc.h:44
zero
static int zero(InterplayACMContext *s, unsigned ind, unsigned col)
Definition: interplayacm.c:121
ff_cbs_read_extradata_from_codec
int ff_cbs_read_extradata_from_codec(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVCodecContext *avctx)
Definition: cbs.c:295
ctu_nz_tl_init
static void ctu_nz_tl_init(TabList *l, VVCFrameContext *fc)
Definition: dec.c:100
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:211
ff_init_cabac_decoder
int ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size)
Definition: cabac.c:162
H2645Packet::nals
H2645NAL * nals
Definition: h2645_parse.h:83
H266RawSliceHeader
Definition: cbs_h266.h:769
min_pu_tl_init
static void min_pu_tl_init(TabList *l, VVCFrameContext *fc)
Definition: dec.c:158
H266RawSliceHeader::num_entry_points
uint32_t num_entry_points
NumEntryPoints.
Definition: cbs_h266.h:836
FF_REFSTRUCT_POOL_FLAG_ZERO_EVERY_TIME
#define FF_REFSTRUCT_POOL_FLAG_ZERO_EVERY_TIME
If this flag is set, the entries will be zeroed before being returned to the user (after the init or ...
Definition: refstruct.h:221
TabList::realloc
int realloc
Definition: dec.c:49
SliceContext::nb_eps
int nb_eps
Definition: dec.h:110
VVCFrame::nb_rpl_elems
int nb_rpl_elems
Definition: dec.h:79
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:523
vvc_decode_init
static av_cold int vvc_decode_init(AVCodecContext *avctx)
Definition: dec.c:1055
VVCFrame::progress
struct FrameProgress * progress
RefStruct reference.
Definition: dec.h:93
ff_vvc_per_frame_init
int ff_vvc_per_frame_init(VVCFrameContext *fc)
Definition: dec.c:413
delta
float delta
Definition: vorbis_enc_data.h:430
ff_vvc_decode_aps
int ff_vvc_decode_aps(VVCParamSets *ps, const CodedBitstreamUnit *unit)
Definition: ps.c:1145
H266RawSlice::header_size
size_t header_size
Definition: cbs_h266.h:846
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
init_default_scale_m
static av_cold void init_default_scale_m(void)
Definition: dec.c:1049
av_frame_move_ref
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
Definition: frame.c:635
VVC_IDR_N_LP
@ VVC_IDR_N_LP
Definition: vvc.h:37
H266RawSlice::data_size
size_t data_size
Definition: cbs_h266.h:847
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:608
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
EntryPoint
Definition: ctu.h:351
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
wait_delayed_frame
static int wait_delayed_frame(VVCContext *s, AVFrame *output, int *got_output)
Definition: dec.c:924
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
ff_vvc_ps_uninit
void ff_vvc_ps_uninit(VVCParamSets *ps)
Definition: ps.c:956
ret
ret
Definition: filter_design.txt:187
VVCFrame::frame
struct AVFrame * frame
Definition: dec.h:72
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
vvc_decode_flush
static av_cold void vvc_decode_flush(AVCodecContext *avctx)
Definition: dec.c:1013
vvc_decode_frame
static int vvc_decode_frame(AVCodecContext *avctx, AVFrame *output, int *got_output, AVPacket *avpkt)
Definition: dec.c:984
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
msm_tl_init
static void msm_tl_init(TabList *l, VVCFrameContext *fc)
Definition: dec.c:264
ff_refstruct_replace
void ff_refstruct_replace(void *dstp, const void *src)
Ensure *dstp refers to the same object as src.
Definition: refstruct.c:160
VVC_PPS_NUT
@ VVC_PPS_NUT
Definition: vvc.h:45
ff_vvc_executor_alloc
AVExecutor * ff_vvc_executor_alloc(VVCContext *s, const int thread_count)
Definition: thread.c:682
AVCodecContext
main external API structure.
Definition: avcodec.h:445
VVC_PREFIX_APS_NUT
@ VVC_PREFIX_APS_NUT
Definition: vvc.h:46
tl_zero
static int tl_zero(TabList *l)
Definition: dec.c:89
VVCFrame::poc
int poc
Definition: dec.h:83
TabList::zero
int zero
Definition: dec.c:48
VVC_SUFFIX_APS_NUT
@ VVC_SUFFIX_APS_NUT
Definition: vvc.h:47
Tab::size
size_t size
Definition: dec.c:41
slice_start
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
Definition: dec.c:737
pps
uint64_t pps
Definition: dovi_rpuenc.c:35
imf
#define imf
Definition: vf_colormatrix.c:113
min_pu_nz_tl_init
static void min_pu_nz_tl_init(TabList *l, VVCFrameContext *fc)
Definition: dec.c:169
AV_CODEC_CAP_DELAY
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: codec.h:76
VVC_CRA_NUT
@ VVC_CRA_NUT
Definition: vvc.h:38
ff_vvc_set_new_ref
int ff_vvc_set_new_ref(VVCContext *s, VVCFrameContext *fc, AVFrame **frame)
Definition: refs.c:169
ff_cbs_read_packet
int ff_cbs_read_packet(CodedBitstreamContext *ctx, CodedBitstreamFragment *frag, const AVPacket *pkt)
Read the data bitstream from a packet into a fragment, then split into units and decompose.
Definition: cbs.c:304
frame_start
static int frame_start(VVCContext *s, VVCFrameContext *fc, SliceContext *sc)
Definition: dec.c:703
ALF_BORDER_CHROMA
#define ALF_BORDER_CHROMA
Definition: ctu.h:77
ff_vvc_frame_rpl
int ff_vvc_frame_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc)
Definition: refs.c:521
VVC_MAX_SAMPLE_ARRAYS
@ VVC_MAX_SAMPLE_ARRAYS
Definition: vvc.h:77
ff_vvc_profiles
const AVProfile ff_vvc_profiles[]
Definition: profiles.c:91
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
FF_CODEC_CAP_AUTO_THREADS
#define FF_CODEC_CAP_AUTO_THREADS
Codec handles avctx->thread_count == 0 (auto) internally.
Definition: codec_internal.h:72
tl_init
static void tl_init(TabList *l, const int zero, const int realloc)
Definition: dec.c:59
ff_cbs_init
av_cold int ff_cbs_init(CodedBitstreamContext **ctx_ptr, enum AVCodecID codec_id, void *log_ctx)
Create and initialise a new context for the given codec.
Definition: cbs.c:90
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
frame_context_for_each_tl
static int frame_context_for_each_tl(VVCFrameContext *fc, int(*unary_fn)(TabList *l))
Definition: dec.c:318
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
AVPacket
This structure stores compressed data.
Definition: packet.h:510
decode_nal_units
static int decode_nal_units(VVCContext *s, VVCFrameContext *fc, AVPacket *avpkt)
Definition: dec.c:873
SliceContext::sh
VVCSH sh
Definition: dec.h:108
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
ep_init_cabac_decoder
static int ep_init_cabac_decoder(SliceContext *sc, const int index, const H2645NAL *nal, GetBitContext *gb, const CodedBitstreamUnit *unit)
Definition: dec.c:512
VVCFrameContext
Definition: dec.h:115
min_positive
static int min_positive(const int idx, const int diff, const int min_diff)
Definition: dec.c:418
EntryPoint::ctu_start
int ctu_start
Definition: ctu.h:359
IS_I
#define IS_I(rsh)
Definition: ps.h:38
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
thread.h
TAB_MAX
#define TAB_MAX
Definition: dec.c:37
VVC_EOB_NUT
@ VVC_EOB_NUT
Definition: vvc.h:51
frame_context_free
static av_cold void frame_context_free(VVCFrameContext *fc)
Definition: dec.c:628
h
h
Definition: vp9dsp_template.c:2070
ctu.h
VVCFrame::ctb_count
int ctb_count
Definition: dec.h:81
VVCFrame::rpl_tab
RefPicListTab ** rpl_tab
RefStruct reference.
Definition: dec.h:77
VVCFrame::ref_width
int ref_width
CurrPicScalWinWidthL.
Definition: dec.h:88
int
int
Definition: ffmpeg_filter.c:424
ff_refstruct_unref
void ff_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:375
VVCFrame::sps
const VVCSPS * sps
RefStruct reference.
Definition: dec.h:74
ff_vvc_bump_frame
void ff_vvc_bump_frame(VVCContext *s, VVCFrameContext *fc)
Definition: refs.c:270
H266RawSlice
Definition: cbs_h266.h:841
VVCContext
Definition: dec.h:214
dec.h
max_negtive
static int max_negtive(const int idx, const int diff, const int max_diff)
Definition: dec.c:423
Tab::tab
void ** tab
Definition: dec.c:40
ff_vvc_ctu_free_cus
void ff_vvc_ctu_free_cus(CodingUnit **cus)
Definition: ctu.c:2534