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