FFmpeg
vvc_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 
25 #include "libavutil/mem.h"
26 #include "libavutil/thread.h"
27 #include "libavcodec/refstruct.h"
28 #include "libavcodec/thread.h"
29 
30 #include "vvc_refs.h"
31 
32 #define VVC_FRAME_FLAG_OUTPUT (1 << 0)
33 #define VVC_FRAME_FLAG_SHORT_REF (1 << 1)
34 #define VVC_FRAME_FLAG_LONG_REF (1 << 2)
35 #define VVC_FRAME_FLAG_BUMPING (1 << 3)
36 
37 typedef struct FrameProgress {
42  uint8_t has_lock;
43  uint8_t has_cond;
45 
47 {
48  /* frame->frame can be NULL if context init failed */
49  if (!frame->frame || !frame->frame->buf[0])
50  return;
51 
52  frame->flags &= ~flags;
53  if (!frame->flags) {
54  av_frame_unref(frame->frame);
55  ff_refstruct_unref(&frame->progress);
56 
57  ff_refstruct_unref(&frame->tab_dmvr_mvf);
58 
60  frame->nb_rpl_elems = 0;
61  ff_refstruct_unref(&frame->rpl_tab);
62 
63  frame->collocated_ref = NULL;
64  }
65 }
66 
67 const RefPicList *ff_vvc_get_ref_list(const VVCFrameContext *fc, const VVCFrame *ref, int x0, int y0)
68 {
69  const int x_cb = x0 >> fc->ps.sps->ctb_log2_size_y;
70  const int y_cb = y0 >> fc->ps.sps->ctb_log2_size_y;
71  const int pic_width_cb = fc->ps.pps->ctb_width;
72  const int ctb_addr_rs = y_cb * pic_width_cb + x_cb;
73 
74  return (const RefPicList *)ref->rpl_tab[ctb_addr_rs];
75 }
76 
78 {
79  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
80  ff_vvc_unref_frame(fc, &fc->DPB[i],
82 }
83 
85 {
86  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
87  ff_vvc_unref_frame(fc, &fc->DPB[i], ~0);
88 }
89 
90 static void free_progress(FFRefStructOpaque unused, void *obj)
91 {
92  FrameProgress *p = (FrameProgress *)obj;
93 
94  if (p->has_cond)
95  ff_cond_destroy(&p->cond);
96  if (p->has_lock)
98 }
99 
101 {
103 
104  if (p) {
105  p->has_lock = !ff_mutex_init(&p->lock, NULL);
106  p->has_cond = !ff_cond_init(&p->cond, NULL);
107  if (!p->has_lock || !p->has_cond)
108  ff_refstruct_unref(&p);
109  }
110  return p;
111 }
112 
114 {
115  const VVCPPS *pps = fc->ps.pps;
116  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
117  int ret;
118  VVCFrame *frame = &fc->DPB[i];
119  if (frame->frame->buf[0])
120  continue;
121 
123  if (ret < 0)
124  return NULL;
125 
126  frame->rpl = ff_refstruct_allocz(s->current_frame.nb_units * sizeof(RefPicListTab));
127  if (!frame->rpl)
128  goto fail;
129  frame->nb_rpl_elems = s->current_frame.nb_units;
130 
131  frame->tab_dmvr_mvf = ff_refstruct_pool_get(fc->tab_dmvr_mvf_pool);
132  if (!frame->tab_dmvr_mvf)
133  goto fail;
134 
135  frame->rpl_tab = ff_refstruct_pool_get(fc->rpl_tab_pool);
136  if (!frame->rpl_tab)
137  goto fail;
138  frame->ctb_count = pps->ctb_width * pps->ctb_height;
139  for (int j = 0; j < frame->ctb_count; j++)
140  frame->rpl_tab[j] = frame->rpl;
141 
142  frame->progress = alloc_progress();
143  if (!frame->progress)
144  goto fail;
145 
146  return frame;
147 fail:
149  return NULL;
150  }
151  av_log(s->avctx, AV_LOG_ERROR, "Error allocating frame, DPB full.\n");
152  return NULL;
153 }
154 
156 {
157  const VVCPH *ph= &fc->ps.ph;
158  const int poc = ph->poc;
159  VVCFrame *ref;
160 
161  /* check that this POC doesn't already exist */
162  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
163  VVCFrame *frame = &fc->DPB[i];
164 
165  if (frame->frame->buf[0] && frame->sequence == s->seq_decode &&
166  frame->poc == poc) {
167  av_log(s->avctx, AV_LOG_ERROR, "Duplicate POC in a sequence: %d.\n", poc);
168  return AVERROR_INVALIDDATA;
169  }
170  }
171 
172  ref = alloc_frame(s, fc);
173  if (!ref)
174  return AVERROR(ENOMEM);
175 
176  *frame = ref->frame;
177  fc->ref = ref;
178 
179  if (s->no_output_before_recovery_flag && (IS_RASL(s) || !GDR_IS_RECOVERED(s)))
180  ref->flags = 0;
181  else if (ph->r->ph_pic_output_flag)
182  ref->flags = VVC_FRAME_FLAG_OUTPUT;
183 
184  if (!ph->r->ph_non_ref_pic_flag)
185  ref->flags |= VVC_FRAME_FLAG_SHORT_REF;
186 
187  ref->poc = poc;
188  ref->sequence = s->seq_decode;
189  ref->frame->crop_left = fc->ps.pps->r->pps_conf_win_left_offset << fc->ps.sps->hshift[CHROMA];
190  ref->frame->crop_right = fc->ps.pps->r->pps_conf_win_right_offset << fc->ps.sps->hshift[CHROMA];
191  ref->frame->crop_top = fc->ps.pps->r->pps_conf_win_top_offset << fc->ps.sps->vshift[CHROMA];
192  ref->frame->crop_bottom = fc->ps.pps->r->pps_conf_win_bottom_offset << fc->ps.sps->vshift[CHROMA];
193 
194  return 0;
195 }
196 
197 int ff_vvc_output_frame(VVCContext *s, VVCFrameContext *fc, AVFrame *out, const int no_output_of_prior_pics_flag, int flush)
198 {
199  const VVCSPS *sps = fc->ps.sps;
200  do {
201  int nb_output = 0;
202  int min_poc = INT_MAX;
203  int min_idx, ret;
204 
205  if (no_output_of_prior_pics_flag) {
206  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
207  VVCFrame *frame = &fc->DPB[i];
208  if (!(frame->flags & VVC_FRAME_FLAG_BUMPING) && frame->poc != fc->ps.ph.poc &&
209  frame->sequence == s->seq_output) {
211  }
212  }
213  }
214 
215  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
216  VVCFrame *frame = &fc->DPB[i];
217  if ((frame->flags & VVC_FRAME_FLAG_OUTPUT) &&
218  frame->sequence == s->seq_output) {
219  nb_output++;
220  if (frame->poc < min_poc || nb_output == 1) {
221  min_poc = frame->poc;
222  min_idx = i;
223  }
224  }
225  }
226 
227  /* wait for more frames before output */
228  if (!flush && s->seq_output == s->seq_decode && sps &&
229  nb_output <= sps->r->sps_dpb_params.dpb_max_dec_pic_buffering_minus1[sps->r->sps_max_sublayers_minus1] + 1)
230  return 0;
231 
232  if (nb_output) {
233  VVCFrame *frame = &fc->DPB[min_idx];
234 
235  ret = av_frame_ref(out, frame->frame);
236  if (frame->flags & VVC_FRAME_FLAG_BUMPING)
238  else
240  if (ret < 0)
241  return ret;
242 
243  av_log(s->avctx, AV_LOG_DEBUG,
244  "Output frame with POC %d.\n", frame->poc);
245  return 1;
246  }
247 
248  if (s->seq_output != s->seq_decode)
249  s->seq_output = (s->seq_output + 1) & 0xff;
250  else
251  break;
252  } while (1);
253  return 0;
254 }
255 
257 {
258  const VVCSPS *sps = fc->ps.sps;
259  const int poc = fc->ps.ph.poc;
260  int dpb = 0;
261  int min_poc = INT_MAX;
262 
263  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
264  VVCFrame *frame = &fc->DPB[i];
265  if ((frame->flags) &&
266  frame->sequence == s->seq_output &&
267  frame->poc != poc) {
268  dpb++;
269  }
270  }
271 
272  if (sps && dpb >= sps->r->sps_dpb_params.dpb_max_dec_pic_buffering_minus1[sps->r->sps_max_sublayers_minus1] + 1) {
273  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
274  VVCFrame *frame = &fc->DPB[i];
275  if ((frame->flags) &&
276  frame->sequence == s->seq_output &&
277  frame->poc != poc) {
278  if (frame->flags == VVC_FRAME_FLAG_OUTPUT && frame->poc < min_poc) {
279  min_poc = frame->poc;
280  }
281  }
282  }
283 
284  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
285  VVCFrame *frame = &fc->DPB[i];
286  if (frame->flags & VVC_FRAME_FLAG_OUTPUT &&
287  frame->sequence == s->seq_output &&
288  frame->poc <= min_poc) {
289  frame->flags |= VVC_FRAME_FLAG_BUMPING;
290  }
291  }
292 
293  dpb--;
294  }
295 }
296 
297 static VVCFrame *find_ref_idx(VVCContext *s, VVCFrameContext *fc, int poc, uint8_t use_msb)
298 {
299  const int mask = use_msb ? ~0 : fc->ps.sps->max_pic_order_cnt_lsb - 1;
300 
301  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
302  VVCFrame *ref = &fc->DPB[i];
303  if (ref->frame->buf[0] && ref->sequence == s->seq_decode) {
304  if ((ref->poc & mask) == poc)
305  return ref;
306  }
307  }
308  return NULL;
309 }
310 
311 static void mark_ref(VVCFrame *frame, int flag)
312 {
314  frame->flags |= flag;
315 }
316 
318 {
319  const VVCSPS *sps = fc->ps.sps;
320  const VVCPPS *pps = fc->ps.pps;
321  VVCFrame *frame;
322 
323  frame = alloc_frame(s, fc);
324  if (!frame)
325  return NULL;
326 
327  if (!s->avctx->hwaccel) {
328  if (!sps->pixel_shift) {
329  for (int i = 0; frame->frame->buf[i]; i++)
330  memset(frame->frame->buf[i]->data, 1 << (sps->bit_depth - 1),
331  frame->frame->buf[i]->size);
332  } else {
333  for (int i = 0; frame->frame->data[i]; i++)
334  for (int y = 0; y < (pps->height >> sps->vshift[i]); y++) {
335  uint8_t *dst = frame->frame->data[i] + y * frame->frame->linesize[i];
336  AV_WN16(dst, 1 << (sps->bit_depth - 1));
337  av_memcpy_backptr(dst + 2, 2, 2*(pps->width >> sps->hshift[i]) - 2);
338  }
339  }
340  }
341 
342  frame->poc = poc;
343  frame->sequence = s->seq_decode;
344  frame->flags = 0;
345 
347 
348  return frame;
349 }
350 
351 /* add a reference with the given poc to the list and mark it as used in DPB */
353  int poc, int ref_flag, uint8_t use_msb)
354 {
355  VVCFrame *ref = find_ref_idx(s, fc, poc, use_msb);
356 
357  if (ref == fc->ref || list->nb_refs >= VVC_MAX_REF_ENTRIES)
358  return AVERROR_INVALIDDATA;
359 
360  if (!ref) {
361  ref = generate_missing_ref(s, fc, poc);
362  if (!ref)
363  return AVERROR(ENOMEM);
364  }
365 
366  list->list[list->nb_refs] = poc;
367  list->ref[list->nb_refs] = ref;
368  list->isLongTerm[list->nb_refs] = ref_flag & VVC_FRAME_FLAG_LONG_REF;
369  list->nb_refs++;
370 
371  mark_ref(ref, ref_flag);
372  return 0;
373 }
374 
376 {
377  VVCFrame *frame = fc->ref;
378  const VVCSH *sh = &sc->sh;
379 
380  if (sc->slice_idx >= frame->nb_rpl_elems)
381  return AVERROR_INVALIDDATA;
382 
383  for (int i = 0; i < sh->num_ctus_in_curr_slice; i++) {
384  const int rs = sh->ctb_addr_in_curr_slice[i];
385  frame->rpl_tab[rs] = frame->rpl + sc->slice_idx;
386  }
387 
388  sc->rpl = frame->rpl_tab[sh->ctb_addr_in_curr_slice[0]]->refPicList;
389 
390  return 0;
391 }
392 
393 static int delta_poc_st(const H266RefPicListStruct *rpls,
394  const int lx, const int i, const VVCSPS *sps)
395 {
396  int abs_delta_poc_st = rpls->abs_delta_poc_st[i];
397  if (!((sps->r->sps_weighted_pred_flag ||
398  sps->r->sps_weighted_bipred_flag) && i != 0))
399  abs_delta_poc_st++;
400  return (1 - 2 * rpls->strp_entry_sign_flag[i]) * abs_delta_poc_st;
401 }
402 
403 static int poc_lt(int *prev_delta_poc_msb, const int poc, const H266RefPicLists *ref_lists,
404  const int lx, const int j, const int max_poc_lsb)
405 {
406  const H266RefPicListStruct *rpls = ref_lists->rpl_ref_list + lx;
407  int lt_poc = rpls->ltrp_in_header_flag ? ref_lists->poc_lsb_lt[lx][j] : rpls->rpls_poc_lsb_lt[j];
408 
409  if (ref_lists->delta_poc_msb_cycle_present_flag[lx][j]) {
410  const uint32_t delta = ref_lists->delta_poc_msb_cycle_lt[lx][j] + *prev_delta_poc_msb;
411  lt_poc += poc - delta * max_poc_lsb - (poc & (max_poc_lsb - 1));
412  *prev_delta_poc_msb = delta;
413  }
414  return lt_poc;
415 }
416 
418 {
419  const VVCSPS *sps = fc->ps.sps;
420  const H266RawPPS *pps = fc->ps.pps->r;
421  const VVCPH *ph = &fc->ps.ph;
422  const H266RawSliceHeader *rsh = sc->sh.r;
423  const int max_poc_lsb = sps->max_pic_order_cnt_lsb;
424  const H266RefPicLists *ref_lists =
425  pps->pps_rpl_info_in_ph_flag ? &ph->r->ph_ref_pic_lists : &rsh->sh_ref_pic_lists;
426  int ret = 0;
427 
428  ret = init_slice_rpl(fc, sc);
429  if (ret < 0)
430  return ret;
431 
432  for (int lx = L0; lx <= L1; lx++) {
433  const H266RefPicListStruct *rpls = ref_lists->rpl_ref_list + lx;
434  RefPicList *rpl = sc->rpl + lx;
435  int poc_base = ph->poc;
436  int prev_delta_poc_msb = 0;
437 
438  rpl->nb_refs = 0;
439  for (int i = 0, j = 0; i < rpls->num_ref_entries; i++) {
440  int poc;
441  if (!rpls->inter_layer_ref_pic_flag[i]) {
442  int use_msb = 1;
443  int ref_flag;
444  if (rpls->st_ref_pic_flag[i]) {
445  poc = poc_base + delta_poc_st(rpls, lx, i, sps);
446  poc_base = poc;
447  ref_flag = VVC_FRAME_FLAG_SHORT_REF;
448  } else {
449  use_msb = ref_lists->delta_poc_msb_cycle_present_flag[lx][j];
450  poc = poc_lt(&prev_delta_poc_msb, ph->poc, ref_lists, lx, j, max_poc_lsb);
451  ref_flag = VVC_FRAME_FLAG_LONG_REF;
452  j++;
453  }
454  ret = add_candidate_ref(s, fc, rpl, poc, ref_flag, use_msb);
455  if (ret < 0)
456  return ret;
457  } else {
458  // OPI_B_3.bit and VPS_A_3.bit should cover this
459  avpriv_report_missing_feature(fc->log_ctx, "Inter layer ref");
461  return ret;
462  }
463  }
464  if ((!rsh->sh_collocated_from_l0_flag) == lx &&
465  rsh->sh_collocated_ref_idx < rpl->nb_refs)
466  fc->ref->collocated_ref = rpl->ref[rsh->sh_collocated_ref_idx];
467  }
468  return 0;
469 }
470 
472 {
473  int ret = 0;
474 
475  /* clear the reference flags on all frames except the current one */
476  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++) {
477  VVCFrame *frame = &fc->DPB[i];
478 
479  if (frame == fc->ref)
480  continue;
481 
482  mark_ref(frame, 0);
483  }
484 
485  if ((ret = ff_vvc_slice_rpl(s, fc, sc)) < 0)
486  goto fail;
487 
488 fail:
489  /* release any frames that are now unused */
490  for (int i = 0; i < FF_ARRAY_ELEMS(fc->DPB); i++)
491  ff_vvc_unref_frame(fc, &fc->DPB[i], 0);
492  return ret;
493 }
494 
496 {
499 }
500 
501 static int is_progress_done(const FrameProgress *p, const VVCProgressListener *l)
502 {
503  return p->progress[l->vp] > l->y;
504 }
505 
507 {
508  l->next = *prev;
509  *prev = l;
510 }
511 
513 {
514  *prev = l->next;
515  l->next = NULL;
516  return l;
517 }
518 
520 {
522  VVCProgressListener **prev = &p->listener[vp];
523 
524  while (*prev) {
525  if (is_progress_done(p, *prev)) {
526  VVCProgressListener *l = remove_listener(prev, *prev);
527  add_listener(&list, l);
528  } else {
529  prev = &(*prev)->next;
530  }
531  }
532  return list;
533 }
534 
535 void ff_vvc_report_progress(VVCFrame *frame, const VVCProgress vp, const int y)
536 {
537  FrameProgress *p = frame->progress;
539 
540  ff_mutex_lock(&p->lock);
541 
542  av_assert0(p->progress[vp] < y || p->progress[vp] == INT_MAX);
543  p->progress[vp] = y;
544  l = get_done_listener(p, vp);
545  ff_cond_signal(&p->cond);
546 
547  ff_mutex_unlock(&p->lock);
548 
549  while (l) {
550  l->progress_done(l);
551  l = l->next;
552  }
553 }
554 
556 {
557  FrameProgress *p = frame->progress;
558 
559  ff_mutex_lock(&p->lock);
560 
561  if (is_progress_done(p, l)) {
562  ff_mutex_unlock(&p->lock);
563  l->progress_done(l);
564  } else {
565  add_listener(p->listener + l->vp, l);
566  ff_mutex_unlock(&p->lock);
567  }
568 }
VVCSPS
Definition: vvc_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
add_candidate_ref
static int add_candidate_ref(VVCContext *s, VVCFrameContext *fc, RefPicList *list, int poc, int ref_flag, uint8_t use_msb)
Definition: vvc_refs.c:352
H266RefPicLists::poc_lsb_lt
uint16_t poc_lsb_lt[2][VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:175
VVCSH::num_ctus_in_curr_slice
uint32_t num_ctus_in_curr_slice
NumCtusInCurrSlice.
Definition: vvc_ps.h:233
VVCPH
Definition: vvc_ps.h:147
ff_mutex_init
static int ff_mutex_init(AVMutex *mutex, const void *attr)
Definition: thread.h:187
VVCPPS
Definition: vvc_ps.h:92
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
ff_vvc_report_frame_finished
void ff_vvc_report_frame_finished(VVCFrame *frame)
Definition: vvc_refs.c:495
FrameProgress::has_cond
uint8_t has_cond
Definition: vvc_refs.c:43
thread.h
VVCProgressListener::vp
VVCProgress vp
Definition: vvc_refs.h:48
ff_refstruct_alloc_ext
static void * ff_refstruct_alloc_ext(size_t size, unsigned flags, void *opaque, void(*free_cb)(FFRefStructOpaque opaque, void *obj))
A wrapper around ff_refstruct_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:94
ph
static int FUNC() ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
Definition: cbs_h266_syntax_template.c:3003
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:375
is_progress_done
static int is_progress_done(const FrameProgress *p, const VVCProgressListener *l)
Definition: vvc_refs.c:501
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
VVCSH::r
const H266RawSliceHeader * r
RefStruct reference.
Definition: vvc_ps.h:229
H266RefPicListStruct::st_ref_pic_flag
uint8_t st_ref_pic_flag[VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:164
ff_vvc_slice_rpl
int ff_vvc_slice_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc)
Definition: vvc_refs.c:417
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:464
H266RefPicListStruct::ltrp_in_header_flag
uint8_t ltrp_in_header_flag
Definition: cbs_h266.h:162
FFRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
FrameProgress::cond
AVCond cond
Definition: vvc_refs.c:41
H266RefPicListStruct::num_ref_entries
uint8_t num_ref_entries
Definition: cbs_h266.h:161
free_progress
static void free_progress(FFRefStructOpaque unused, void *obj)
Definition: vvc_refs.c:90
RefPicList
Definition: hevcdec.h:189
thread.h
ff_thread_get_buffer
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before as well as code calling up to before the decode process starts Call have so the codec calls ff_thread_report set FF_CODEC_CAP_ALLOCATE_PROGRESS in FFCodec caps_internal and use ff_thread_get_buffer() to allocate frames. Otherwise decode directly into the user-supplied frames. Call ff_thread_report_progress() after some part of the current picture has decoded. A good place to put this is where draw_horiz_band() is called - add this if it isn 't called anywhere
ff_mutex_unlock
static int ff_mutex_unlock(AVMutex *mutex)
Definition: thread.h:189
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:179
H266RefPicLists::rpl_ref_list
H266RefPicListStruct rpl_ref_list[2]
Definition: cbs_h266.h:174
vvc_refs.h
FrameProgress::listener
VVCProgressListener * listener[VVC_PROGRESS_LAST]
Definition: vvc_refs.c:39
SliceContext::rpl
RefPicList * rpl
Definition: vvcdec.h:88
RefPicList::nb_refs
int nb_refs
Definition: hevcdec.h:193
refstruct.h
H266RefPicLists::delta_poc_msb_cycle_present_flag
uint8_t delta_poc_msb_cycle_present_flag[2][VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:176
ff_vvc_report_progress
void ff_vvc_report_progress(VVCFrame *frame, const VVCProgress vp, const int y)
Definition: vvc_refs.c:535
ff_vvc_unref_frame
void ff_vvc_unref_frame(VVCFrameContext *fc, VVCFrame *frame, int flags)
Definition: vvc_refs.c:46
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
VVC_FRAME_FLAG_LONG_REF
#define VVC_FRAME_FLAG_LONG_REF
Definition: vvc_refs.c:34
mask
static const uint16_t mask[17]
Definition: lzw.c:38
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
s
#define s(width, name)
Definition: cbs_vp9.c:198
SliceContext::slice_idx
int slice_idx
Definition: vvcdec.h:84
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:425
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
VVCSH
Definition: vvc_ps.h:228
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
generate_missing_ref
static VVCFrame * generate_missing_ref(VVCContext *s, VVCFrameContext *fc, int poc)
Definition: vvc_refs.c:317
H266RefPicLists
Definition: cbs_h266.h:171
AVCond
#define AVCond
Definition: thread.h:192
delta_poc_st
static int delta_poc_st(const H266RefPicListStruct *rpls, const int lx, const int i, const VVCSPS *sps)
Definition: vvc_refs.c:393
RefPicList::ref
struct HEVCFrame * ref[HEVC_MAX_REFS]
Definition: hevcdec.h:190
ff_vvc_clear_refs
void ff_vvc_clear_refs(VVCFrameContext *fc)
Definition: vvc_refs.c:77
add_listener
static void add_listener(VVCProgressListener **prev, VVCProgressListener *l)
Definition: vvc_refs.c:506
IS_RASL
#define IS_RASL(s)
Definition: vvc_ps.h:35
H266RefPicListStruct::abs_delta_poc_st
uint8_t abs_delta_poc_st[VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:165
VVC_PROGRESS_MV
@ VVC_PROGRESS_MV
Definition: vvc_refs.h:39
H266RawPPS
Definition: cbs_h266.h:496
ff_vvc_flush_dpb
void ff_vvc_flush_dpb(VVCFrameContext *fc)
Definition: vvc_refs.c:84
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
L0
#define L0
Definition: hevcdec.h:57
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:368
init_slice_rpl
static int init_slice_rpl(const VVCFrameContext *fc, SliceContext *sc)
Definition: vvc_refs.c:375
ff_refstruct_allocz
static void * ff_refstruct_allocz(size_t size)
Equivalent to ff_refstruct_alloc_ext(size, 0, NULL, NULL)
Definition: refstruct.h:105
H266RefPicListStruct::rpls_poc_lsb_lt
uint8_t rpls_poc_lsb_lt[VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:167
RefPicListTab
Definition: hevcdec.h:196
find_ref_idx
static VVCFrame * find_ref_idx(VVCContext *s, VVCFrameContext *fc, int poc, uint8_t use_msb)
Definition: vvc_refs.c:297
H266RawSliceHeader::sh_collocated_ref_idx
uint8_t sh_collocated_ref_idx
Definition: cbs_h266.h:801
SliceContext
Definition: mss12.h:70
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: vvc_refs.c:197
ff_mutex_destroy
static int ff_mutex_destroy(AVMutex *mutex)
Definition: thread.h:190
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: vvc_refs.c:403
H266RawSliceHeader::sh_collocated_from_l0_flag
uint8_t sh_collocated_from_l0_flag
Definition: cbs_h266.h:800
pps
static int FUNC() pps(CodedBitstreamContext *ctx, RWContext *rw, H264RawPPS *current)
Definition: cbs_h264_syntax_template.c:404
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:384
mark_ref
static void mark_ref(VVCFrame *frame, int flag)
Definition: vvc_refs.c:311
VVCProgressListener::y
int y
Definition: vvc_refs.h:49
H266RefPicListStruct
Definition: cbs_h266.h:160
alloc_progress
static FrameProgress * alloc_progress(void)
Definition: vvc_refs.c:100
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.
VVC_PROGRESS_PIXEL
@ VVC_PROGRESS_PIXEL
Definition: vvc_refs.h:40
VVCFrame
Definition: vvcdec.h:56
VVCSH::ctb_addr_in_curr_slice
const uint32_t * ctb_addr_in_curr_slice
CtbAddrInCurrSlice.
Definition: vvc_ps.h:234
ff_mutex_lock
static int ff_mutex_lock(AVMutex *mutex)
Definition: thread.h:188
H266RawSliceHeader
Definition: cbs_h266.h:769
flag
#define flag(name)
Definition: cbs_av1.c:466
VVC_PROGRESS_LAST
@ VVC_PROGRESS_LAST
Definition: vvc_refs.h:41
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
VVC_MAX_REF_ENTRIES
@ VVC_MAX_REF_ENTRIES
Definition: vvc.h:115
delta
float delta
Definition: vorbis_enc_data.h:430
FrameProgress::progress
atomic_int progress[VVC_PROGRESS_LAST]
Definition: vvc_refs.c:38
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:606
VVC_FRAME_FLAG_OUTPUT
#define VVC_FRAME_FLAG_OUTPUT
Definition: vvc_refs.c:32
GDR_IS_RECOVERED
#define GDR_IS_RECOVERED(s)
Definition: vvc_ps.h:43
VVCProgressListener::next
VVCProgressListener * next
Definition: vvc_refs.h:51
H266RefPicLists::delta_poc_msb_cycle_lt
uint16_t delta_poc_msb_cycle_lt[2][VVC_MAX_REF_ENTRIES]
Definition: cbs_h266.h:177
get_done_listener
static VVCProgressListener * get_done_listener(FrameProgress *p, const VVCProgress vp)
Definition: vvc_refs.c:519
ret
ret
Definition: filter_design.txt:187
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
remove_listener
static VVCProgressListener * remove_listener(VVCProgressListener **prev, VVCProgressListener *l)
Definition: vvc_refs.c:512
VVCProgressListener
Definition: vvc_refs.h:47
FrameProgress::lock
AVMutex lock
Definition: vvc_refs.c:40
FrameProgress
Definition: vvc_refs.c:37
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
ff_cond_signal
static int ff_cond_signal(AVCond *cond)
Definition: thread.h:196
ff_vvc_frame_rpl
int ff_vvc_frame_rpl(VVCContext *s, VVCFrameContext *fc, SliceContext *sc)
Definition: vvc_refs.c:471
VVC_FRAME_FLAG_BUMPING
#define VVC_FRAME_FLAG_BUMPING
Definition: vvc_refs.c:35
alloc_frame
static VVCFrame * alloc_frame(VVCContext *s, VVCFrameContext *fc)
Definition: vvc_refs.c:113
VVCProgress
VVCProgress
Definition: vvc_refs.h:38
VVC_FRAME_FLAG_SHORT_REF
#define VVC_FRAME_FLAG_SHORT_REF
Definition: vvc_refs.c:33
FrameProgress::has_lock
uint8_t has_lock
Definition: vvc_refs.c:42
mem.h
ff_vvc_get_ref_list
const RefPicList * ff_vvc_get_ref_list(const VVCFrameContext *fc, const VVCFrame *ref, int x0, int y0)
Definition: vvc_refs.c:67
ff_cond_destroy
static int ff_cond_destroy(AVCond *cond)
Definition: thread.h:195
VVCProgressListener::progress_done
progress_done_fn progress_done
Definition: vvc_refs.h:50
SliceContext::sh
VVCSH sh
Definition: vvcdec.h:85
VVCFrameContext
Definition: vvcdec.h:92
H266RawSliceHeader::sh_ref_pic_lists
H266RefPicLists sh_ref_pic_lists
Definition: cbs_h266.h:795
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
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
ff_vvc_set_new_ref
int ff_vvc_set_new_ref(VVCContext *s, VVCFrameContext *fc, AVFrame **frame)
Definition: vvc_refs.c:155
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
ff_refstruct_pool_get
void * ff_refstruct_pool_get(FFRefStructPool *pool)
Get an object from the pool, reusing an old one from the pool when available.
Definition: refstruct.c:297
VVCContext
Definition: vvcdec.h:195
ff_vvc_add_progress_listener
void ff_vvc_add_progress_listener(VVCFrame *frame, VVCProgressListener *l)
Definition: vvc_refs.c:555
ff_vvc_bump_frame
void ff_vvc_bump_frame(VVCContext *s, VVCFrameContext *fc)
Definition: vvc_refs.c:256
AV_WN16
#define AV_WN16(p, v)
Definition: intreadwrite.h:370