FFmpeg
inter.c
Go to the documentation of this file.
1 /*
2  * VVC inter prediction
3  *
4  * Copyright (C) 2022 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 #include "libavutil/frame.h"
23 
24 #include "data.h"
25 #include "inter.h"
26 #include "mvs.h"
27 #include "refs.h"
28 
29 // +1 is enough, + 32 for asm alignment
30 #define PROF_TEMP_OFFSET (MAX_PB_SIZE + 32)
31 static const int bcw_w_lut[] = {4, 5, 3, 10, -2};
32 
33 static void subpic_get_rect(VVCRect *r, const VVCFrame *src_frame, const int subpic_idx, const int is_chroma)
34 {
35  const VVCSPS *sps = src_frame->sps;
36  const VVCPPS *pps = src_frame->pps;
37  const int hs = sps->hshift[is_chroma];
38  const int vs = sps->vshift[is_chroma];
39 
40  r->l = pps->subpic_x[subpic_idx] >> hs;
41  r->t = pps->subpic_y[subpic_idx] >> vs;
42  r->r = r->l + (pps->subpic_width[subpic_idx] >> hs);
43  r->b = r->t + (pps->subpic_height[subpic_idx] >> vs);
44 }
45 
46 // clip to subblock and subpicture process in 8.5.6.3.2 Luma sample interpolation filtering process
47 static void clip_to_subpic(int *x_off, int *y_off, int *pic_width, int *pic_height, const VVCRect *subpic, const VVCRect *sb, const int dmvr_clip)
48 {
49  const int l = dmvr_clip ? FFMIN(FFMAX(subpic->l, sb->l), subpic->r - 1) : subpic->l;
50  const int t = dmvr_clip ? FFMIN(FFMAX(subpic->t, sb->t), subpic->b - 1) : subpic->t;
51  const int r = dmvr_clip ? FFMAX(FFMIN(subpic->r, sb->r), subpic->l + 1) : subpic->r;
52  const int b = dmvr_clip ? FFMAX(FFMIN(subpic->b, sb->b), subpic->t + 1) : subpic->b;
53 
54  *x_off -= l;
55  *y_off -= t;
56  *pic_width = r - l;
57  *pic_height = b - t;
58 }
59 
60 static void emulated_edge_no_wrap(const VVCLocalContext *lc, uint8_t *dst,
61  const uint8_t **src, ptrdiff_t *src_stride,
62  int x_off, int y_off, const int block_w, const int block_h,
63  const int extra_before, const int extra_after,
64  const VVCRect *subpic, const VVCRect *sb, const int dmvr_clip)
65 {
66  const VVCFrameContext *fc = lc->fc;
67  const int extra = extra_before + extra_after;
68  int pic_width, pic_height;
69 
70  *src += y_off * *src_stride + (x_off * (1 << fc->ps.sps->pixel_shift));
71 
72  clip_to_subpic(&x_off, &y_off, &pic_width, &pic_height, subpic, sb, dmvr_clip);
73 
74  if (dmvr_clip || x_off < extra_before || y_off < extra_before ||
75  x_off >= pic_width - block_w - extra_after ||
76  y_off >= pic_height - block_h - extra_after) {
77  const int ps = fc->ps.sps->pixel_shift;
78  const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << ps;
79  const int offset = extra_before * *src_stride + (extra_before << ps);
80  const int buf_offset = extra_before * edge_emu_stride + (extra_before << ps);
81 
82  fc->vdsp.emulated_edge_mc(dst, *src - offset, edge_emu_stride, *src_stride,
83  block_w + extra, block_h + extra, x_off - extra_before, y_off - extra_before,
84  pic_width, pic_height);
85 
86  *src = dst + buf_offset;
87  *src_stride = edge_emu_stride;
88  }
89 }
90 
91 static void emulated_half(const VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
92  const uint8_t *src, const ptrdiff_t src_stride, const int ps,
93  int x_off, int y_off, const int block_w, const int block_h,
94  const VVCRect *subpic,const VVCRect *half_sb, const int dmvr_clip)
95 {
96  const VVCFrameContext *fc = lc->fc;
97  int pic_width, pic_height;
98 
99  src += y_off * src_stride + x_off * (1 << ps);
100 
101  clip_to_subpic(&x_off, &y_off, &pic_width, &pic_height, subpic, half_sb, dmvr_clip);
102 
103  fc->vdsp.emulated_edge_mc(dst, src, dst_stride, src_stride,
104  block_w, block_h, x_off, y_off, pic_width, pic_height);
105 }
106 
107 static void sb_set_lr(VVCRect *sb, const int l, const int r)
108 {
109  sb->l = l;
110  sb->r = r;
111 }
112 
113 static void sb_wrap(VVCRect *sb, const int wrap)
114 {
115  sb_set_lr(sb, sb->l + wrap, sb->r + wrap);
116 }
117 
118 static void emulated_edge(const VVCLocalContext *lc, uint8_t *dst,
119  const uint8_t **src, ptrdiff_t *src_stride, const VVCFrame *src_frame,
120  int x_sb, int y_sb, int x_off, int y_off, int block_w, int block_h, const int wrap_enabled,
121  const int is_chroma, const int extra_before, const int extra_after)
122 {
123  const VVCSPS *sps = src_frame->sps;
124  const VVCPPS *pps = src_frame->pps;
125  const int ps = sps->pixel_shift;
126  const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
127  const int extra = extra_before + extra_after;
128  const int dmvr_clip = x_sb != x_off || y_sb != y_off;
129  const int dmvr_left = FFMAX(x_off, x_sb) - extra_before;
130  const int dmvr_right = FFMIN(x_off, x_sb) + block_w + extra_after;
131  const int left = x_off - extra_before;
132  const int top = y_off - extra_before;
133  const int pic_width = pps->width >> sps->hshift[is_chroma];
134  const int wrap = pps->ref_wraparound_offset << (sps->min_cb_log2_size_y - sps->hshift[is_chroma]);
135  const ptrdiff_t dst_stride = EDGE_EMU_BUFFER_STRIDE << ps;
136  VVCRect sb = { x_sb - extra_before, y_sb - extra_before, x_sb + block_w + extra_after, y_sb + block_h + extra_after };
137  VVCRect subpic;
138 
139  subpic_get_rect(&subpic, src_frame, subpic_idx, is_chroma);
140 
141  if (!wrap_enabled || (dmvr_left >= 0 && dmvr_right <= pic_width)) {
142  emulated_edge_no_wrap(lc, dst, src, src_stride,
143  x_off, y_off, block_w, block_h, extra_before, extra_after, &subpic, &sb, dmvr_clip);
144  return;
145  }
146  if (dmvr_right <= 0) {
147  sb_wrap(&sb, wrap);
148  emulated_edge_no_wrap(lc, dst, src, src_stride,
149  x_off + wrap, y_off, block_w, block_h, extra_before, extra_after, &subpic, &sb, dmvr_clip);
150  return;
151  }
152  if (dmvr_left >= pic_width) {
153  sb_wrap(&sb, -wrap);
154  emulated_edge_no_wrap(lc, dst, src, src_stride,
155  x_off - wrap, y_off, block_w, block_h, extra_before, extra_after, &subpic, &sb, dmvr_clip);
156  return;
157  }
158 
159  block_w += extra;
160  block_h += extra;
161 
162  // half block are wrapped
163  if (dmvr_left < 0 ) {
164  const int w = -left;
165  VVCRect half_sb = { sb.l + wrap, sb.t, 0 + wrap, sb.b };
166  emulated_half(lc, dst, dst_stride, *src, *src_stride, ps,
167  left + wrap, top, w, block_h, &subpic, &half_sb, dmvr_clip);
168 
169  sb_set_lr(&half_sb, 0, sb.r);
170  emulated_half(lc, dst + (w << ps), dst_stride, *src, *src_stride, ps,
171  0, top, block_w - w, block_h, &subpic, &half_sb, dmvr_clip);
172  } else {
173  const int w = pic_width - left;
174  VVCRect half_sb = { sb.l, sb.t, pic_width, sb.b };
175  emulated_half(lc, dst, dst_stride, *src, *src_stride, ps,
176  left, top, w, block_h, &subpic, &half_sb, dmvr_clip);
177 
178  sb_set_lr(&half_sb, pic_width - wrap, sb.r - wrap);
179  emulated_half(lc, dst + (w << ps), dst_stride, *src, *src_stride, ps,
180  pic_width - wrap , top, block_w - w, block_h, &subpic, &half_sb, dmvr_clip);
181  }
182 
183  *src = dst + extra_before * dst_stride + (extra_before << ps);
184  *src_stride = dst_stride;
185 }
186 
187 #define MC_EMULATED_EDGE(dst, src, src_stride, x_off, y_off) \
188  emulated_edge(lc, dst, src, src_stride, ref, x_off, y_off, x_off, y_off, block_w, block_h, wrap_enabled, is_chroma, \
189  is_chroma ? CHROMA_EXTRA_BEFORE : LUMA_EXTRA_BEFORE, is_chroma ? CHROMA_EXTRA_AFTER : LUMA_EXTRA_AFTER)
190 
191 #define MC_EMULATED_EDGE_DMVR(dst, src, src_stride, x_sb, y_sb, x_off, y_off) \
192  emulated_edge(lc, dst, src, src_stride, ref, x_sb, y_sb, x_off, y_off, block_w, block_h, wrap_enabled, is_chroma, \
193  is_chroma ? CHROMA_EXTRA_BEFORE : LUMA_EXTRA_BEFORE, is_chroma ? CHROMA_EXTRA_AFTER : LUMA_EXTRA_AFTER)
194 
195 #define MC_EMULATED_EDGE_BILINEAR(dst, src, src_stride, x_off, y_off) \
196  emulated_edge(lc, dst, src, src_stride, ref, x_off, y_off, x_off, y_off, pred_w, pred_h, wrap_enabled, 0, \
197  BILINEAR_EXTRA_BEFORE, BILINEAR_EXTRA_AFTER)
198 
199 // part of 8.5.6.6 Weighted sample prediction process
200 static int derive_weight_uni(int *denom, int *wx, int *ox,
201  const VVCLocalContext *lc, const MvField *mvf, const int c_idx)
202 {
203  const VVCFrameContext *fc = lc->fc;
204  const VVCPPS *pps = fc->ps.pps;
205  const VVCSH *sh = &lc->sc->sh;
206  const int weight_flag = (IS_P(sh->r) && pps->r->pps_weighted_pred_flag) ||
207  (IS_B(sh->r) && pps->r->pps_weighted_bipred_flag);
208  if (weight_flag) {
209  const int lx = mvf->pred_flag - PF_L0;
210  const PredWeightTable *w = pps->r->pps_wp_info_in_ph_flag ? &fc->ps.ph.pwt : &sh->pwt;
211 
212  *denom = w->log2_denom[c_idx > 0];
213  *wx = w->weight[lx][c_idx][mvf->ref_idx[lx]];
214  *ox = w->offset[lx][c_idx][mvf->ref_idx[lx]];
215  }
216  return weight_flag;
217 }
218 
219 // part of 8.5.6.6 Weighted sample prediction process
220 static void apply_averaging(uint8_t *dst, const ptrdiff_t dst_stride,
221  const int16_t *src0, const int16_t *src1, int width, int height,
222  const VVCLocalContext *lc, const MvField *mvf, const int c_idx, const int dmvr_flag)
223 {
224  const VVCFrameContext *fc = lc->fc;
225  const VVCPPS *pps = fc->ps.pps;
226  const VVCSH *sh = &lc->sc->sh;
227  const int bcw_idx = mvf->bcw_idx;
228  av_assert2(IS_B(sh->r));
229  const int weight_flag = pps->r->pps_weighted_bipred_flag && !dmvr_flag;
230  if ((!weight_flag && !bcw_idx) || (bcw_idx && lc->cu->ciip_flag)) {
231  fc->vvcdsp.inter.avg(dst, dst_stride, src0, src1, width, height);
232  return;
233  }
234 
235  int denom, w0, w1, o1, o2;
236  if (bcw_idx) {
237  denom = 2;
238  w1 = bcw_w_lut[bcw_idx];
239  w0 = 8 - w1;
240  o1 = o2 = 0;
241  } else {
242  const PredWeightTable *w = pps->r->pps_wp_info_in_ph_flag ? &fc->ps.ph.pwt : &sh->pwt;
243 
244  denom = w->log2_denom[c_idx > 0];
245  w0 = w->weight[L0][c_idx][mvf->ref_idx[L0]];
246  w1 = w->weight[L1][c_idx][mvf->ref_idx[L1]];
247  o1 = w->offset[L0][c_idx][mvf->ref_idx[L0]];
248  o2 = w->offset[L1][c_idx][mvf->ref_idx[L1]];
249  }
250  fc->vvcdsp.inter.w_avg(dst, dst_stride, src0, src1, width, height, denom, w0, w1, o1, o2);
251 }
252 
253 #define INTER_FILTER(t, frac) (is_chroma ? ff_vvc_inter_chroma_filters[t][frac] : ff_vvc_inter_luma_filters[t][frac])
254 
255 static void mc(VVCLocalContext *lc, int16_t *dst, const VVCFrame *ref, const Mv *mv,
256  int x_off, int y_off, const int block_w, const int block_h, const int c_idx)
257 {
258  const VVCFrameContext *fc = lc->fc;
259  const PredictionUnit *pu = &lc->cu->pu;
260  const uint8_t *src = ref->frame->data[c_idx];
261  ptrdiff_t src_stride = ref->frame->linesize[c_idx];
262  const int is_chroma = !!c_idx;
263  const int hs = fc->ps.sps->hshift[c_idx];
264  const int vs = fc->ps.sps->vshift[c_idx];
265  const int idx = av_log2(block_w) - 1;
266  const intptr_t mx = av_zero_extend(mv->x, 4 + hs) << (is_chroma - hs);
267  const intptr_t my = av_zero_extend(mv->y, 4 + vs) << (is_chroma - vs);
268  const int hpel_if_idx = (is_chroma || pu->merge_gpm_flag) ? 0 : pu->mi.hpel_if_idx;
269  const int8_t *hf = INTER_FILTER(hpel_if_idx, mx);
270  const int8_t *vf = INTER_FILTER(hpel_if_idx, my);
271  const int wrap_enabled = fc->ps.pps->r->pps_ref_wraparound_enabled_flag;
272 
273  x_off += mv->x >> (4 + hs);
274  y_off += mv->y >> (4 + vs);
275 
276  MC_EMULATED_EDGE(lc->edge_emu_buffer, &src, &src_stride, x_off, y_off);
277  fc->vvcdsp.inter.put[is_chroma][idx][!!my][!!mx](dst, src, src_stride, block_h, hf, vf, block_w);
278 }
279 
280 static void mc_uni(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
281  const VVCFrame *ref, const MvField *mvf, int x_off, int y_off, const int block_w, const int block_h,
282  const int c_idx)
283 {
284  const VVCFrameContext *fc = lc->fc;
285  const PredictionUnit *pu = &lc->cu->pu;
286  const uint8_t *src = ref->frame->data[c_idx];
287  ptrdiff_t src_stride = ref->frame->linesize[c_idx];
288  const int lx = mvf->pred_flag - PF_L0;
289  const int hs = fc->ps.sps->hshift[c_idx];
290  const int vs = fc->ps.sps->vshift[c_idx];
291  const int idx = av_log2(block_w) - 1;
292  const Mv *mv = &mvf->mv[lx];
293  const int is_chroma = !!c_idx;
294  const intptr_t mx = av_zero_extend(mv->x, 4 + hs) << (is_chroma - hs);
295  const intptr_t my = av_zero_extend(mv->y, 4 + vs) << (is_chroma - vs);
296  const int hpel_if_idx = is_chroma ? 0 : pu->mi.hpel_if_idx;
297  const int8_t *hf = INTER_FILTER(hpel_if_idx, mx);
298  const int8_t *vf = INTER_FILTER(hpel_if_idx, my);
299  const int wrap_enabled = fc->ps.pps->r->pps_ref_wraparound_enabled_flag;
300  int denom, wx, ox;
301 
302  x_off += mv->x >> (4 + hs);
303  y_off += mv->y >> (4 + vs);
304 
305  MC_EMULATED_EDGE(lc->edge_emu_buffer, &src, &src_stride, x_off, y_off);
306  if (derive_weight_uni(&denom, &wx, &ox, lc, mvf, c_idx)) {
307  fc->vvcdsp.inter.put_uni_w[is_chroma][idx][!!my][!!mx](dst, dst_stride, src, src_stride,
308  block_h, denom, wx, ox, hf, vf, block_w);
309  } else {
310  fc->vvcdsp.inter.put_uni[is_chroma][idx][!!my][!!mx](dst, dst_stride, src, src_stride,
311  block_h, hf, vf, block_w);
312  }
313 }
314 
315 static void mc_bi(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
316  const VVCFrame *ref0, const VVCFrame *ref1, const MvField *mvf, const MvField *orig_mv,
317  const int x_off, const int y_off, const int block_w, const int block_h, const int c_idx,
318  const int sb_bdof_flag)
319 {
320  const VVCFrameContext *fc = lc->fc;
321  const PredictionUnit *pu = &lc->cu->pu;
322  const int hs = fc->ps.sps->hshift[c_idx];
323  const int vs = fc->ps.sps->vshift[c_idx];
324  const int idx = av_log2(block_w) - 1;
325  const VVCFrame *refs[] = { ref0, ref1 };
326  int16_t *tmp[] = { lc->tmp + sb_bdof_flag * PROF_TEMP_OFFSET, lc->tmp1 + sb_bdof_flag * PROF_TEMP_OFFSET };
327  const int is_chroma = !!c_idx;
328  const int hpel_if_idx = is_chroma ? 0 : pu->mi.hpel_if_idx;
329 
330  for (int i = L0; i <= L1; i++) {
331  const Mv *mv = mvf->mv + i;
332  const int mx = av_zero_extend(mv->x, 4 + hs) << (is_chroma - hs);
333  const int my = av_zero_extend(mv->y, 4 + vs) << (is_chroma - vs);
334  const int ox = x_off + (mv->x >> (4 + hs));
335  const int oy = y_off + (mv->y >> (4 + vs));
336  const VVCFrame *ref = refs[i];
337  ptrdiff_t src_stride = ref->frame->linesize[c_idx];
338  const uint8_t *src = ref->frame->data[c_idx];
339  const int8_t *hf = INTER_FILTER(hpel_if_idx, mx);
340  const int8_t *vf = INTER_FILTER(hpel_if_idx, my);
341  const int wrap_enabled = fc->ps.pps->r->pps_ref_wraparound_enabled_flag;
342 
343  if (pu->dmvr_flag) {
344  const int x_sb = x_off + (orig_mv->mv[i].x >> (4 + hs));
345  const int y_sb = y_off + (orig_mv->mv[i].y >> (4 + vs));
346 
347  MC_EMULATED_EDGE_DMVR(lc->edge_emu_buffer, &src, &src_stride, x_sb, y_sb, ox, oy);
348  } else {
349  MC_EMULATED_EDGE(lc->edge_emu_buffer, &src, &src_stride, ox, oy);
350  }
351  fc->vvcdsp.inter.put[is_chroma][idx][!!my][!!mx](tmp[i], src, src_stride, block_h, hf, vf, block_w);
352  if (sb_bdof_flag)
353  fc->vvcdsp.inter.bdof_fetch_samples(tmp[i], src, src_stride, mx, my, block_w, block_h);
354  }
355  if (sb_bdof_flag)
356  fc->vvcdsp.inter.apply_bdof(dst, dst_stride, tmp[L0], tmp[L1], block_w, block_h);
357  else
358  apply_averaging(dst, dst_stride, tmp[L0], tmp[L1], block_w, block_h,
359  lc, mvf, c_idx, pu->dmvr_flag);
360 }
361 
362 static const int8_t* inter_filter_scaled(const int scale, const int is_chroma, const int is_affine)
363 {
364 #define SCALE_THRESHOLD_1 20480
365 #define SCALE_THRESHOLD_2 28672
366 
367  const int i = (scale > SCALE_THRESHOLD_2) + (scale > SCALE_THRESHOLD_1);
368 
369  if (!is_chroma) {
370  if (!is_affine)
371  return &ff_vvc_inter_luma_filters[i + !!i][0][0]; //hpel 1 is not needed for scaled
373  }
374 
375  return &ff_vvc_inter_chroma_filters[i][0][0];
376 }
377 #define INTER_FILTER_SCALED(scale) inter_filter_scaled(scale, is_chroma, is_affine)
378 
379 #define SCALED_CHROMA_ADDIN(scale, collocated_flag) (is_chroma ? (collocated_flag ? 0 : 8 * (scale - (1 << 14))) : 0)
380 #define SCALED_REF_SB(off, scaling_off, ref_mv, scale, add, shift) ((((off - (scaling_off << shift)) << (4 + shift)) + ref_mv) * scale + add)
381 #define SCALED_REF(ref_sb, offset, shift) (FFSIGN(ref_sb) * ((FFABS(ref_sb) + (128 << is_chroma)) >> (8 + is_chroma)) + (offset << (10 - shift)) + (32 >> is_chroma))
382 #define SCALED_STEP(scale) ((scale + 8) >> 4)
383 
384 static void scaled_ref_pos_and_step(const VVCLocalContext *lc, const VVCRefPic *refp, const Mv *mv, const int x_off, const int y_off, const int c_idx,
385  int *x, int *y, int *dx, int *dy)
386 {
387  const VVCFrameContext *fc = lc->fc;
388  const VVCSPS *sps = fc->ps.sps;
389  const int is_chroma = !!c_idx;
390  const int hs = sps->hshift[c_idx];
391  const int vs = sps->vshift[c_idx];
392  const int left_offset = fc->ref->scaling_win.left_offset;
393  const int top_offset = fc->ref->scaling_win.top_offset;
394  const int addx = SCALED_CHROMA_ADDIN(refp->scale[0], sps->r->sps_chroma_horizontal_collocated_flag);
395  const int addy = SCALED_CHROMA_ADDIN(refp->scale[1], sps->r->sps_chroma_vertical_collocated_flag);
396  const int refx_sb = SCALED_REF_SB(x_off, left_offset, mv->x, refp->scale[0], addx, hs);
397  const int refy_sb = SCALED_REF_SB(y_off, top_offset, mv->y, refp->scale[1], addy, vs);
398 
399  *x = SCALED_REF(refx_sb, left_offset, hs);
400  *y = SCALED_REF(refy_sb, top_offset, vs);
401  *dx = SCALED_STEP(refp->scale[0]);
402  *dy = SCALED_STEP(refp->scale[1]);
403 }
404 
405 static void emulated_edge_scaled(VVCLocalContext *lc, const uint8_t **src, ptrdiff_t *src_stride, int *src_height,
406  const VVCFrame *ref, const int x, const int y, const int dx, const int dy, const int w, const int h, const int is_chroma)
407 {
408  const int x_off = SCALED_INT(x);
409  const int y_off = SCALED_INT(y);
410  const int x_end = SCALED_INT(x + w * dx);
411  const int y_end = SCALED_INT(y + h * dy);
412  const int x_last = SCALED_INT(x + (w - 1) * dx);
413  const int y_last = SCALED_INT(y + (h - 1) * dy);
414  const int block_w = x_end - x_off + (x_end == x_last);
415  const int block_h = *src_height = y_end - y_off + (y_end == y_last);
416  const int wrap_enabled = 0;
417 
418  MC_EMULATED_EDGE(lc->edge_emu_buffer, src, src_stride, x_off, y_off);
419 }
420 
421 static void mc_scaled(VVCLocalContext *lc, int16_t *dst, const VVCRefPic *refp, const Mv *mv,
422  int x_off, int y_off, const int block_w, const int block_h, const int c_idx)
423 {
424  const VVCFrameContext *fc = lc->fc;
425  const PredictionUnit *pu = &lc->cu->pu;
426  const uint8_t *src = refp->ref->frame->data[c_idx];
427  ptrdiff_t src_stride = refp->ref->frame->linesize[c_idx];
428  const int is_affine = pu->inter_affine_flag;
429  const int is_chroma = !!c_idx;
430  const int idx = av_log2(block_w) - 1;
431  const int8_t *hf = INTER_FILTER_SCALED(refp->scale[0]);
432  const int8_t *vf = INTER_FILTER_SCALED(refp->scale[1]);
433  int x, y, dx, dy, src_height;
434 
435  scaled_ref_pos_and_step(lc, refp, mv, x_off, y_off, c_idx, &x, &y, &dx, &dy);
436  emulated_edge_scaled(lc, &src, &src_stride, &src_height, refp->ref, x, y, dx, dy, block_w, block_h, is_chroma);
437  fc->vvcdsp.inter.put_scaled[is_chroma][idx](dst, src, src_stride, src_height, x, y, dx, dy, block_h, hf, vf, block_w);
438 }
439 
440 static void mc_uni_scaled(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const VVCRefPic *refp,
441  const MvField *mvf, const int x_off, const int y_off, const int block_w, const int block_h, const int c_idx)
442 {
443  const VVCFrameContext *fc = lc->fc;
444  const PredictionUnit *pu = &lc->cu->pu;
445  const uint8_t *src = refp->ref->frame->data[c_idx];
446  ptrdiff_t src_stride = refp->ref->frame->linesize[c_idx];
447  const int lx = mvf->pred_flag - PF_L0;
448  const Mv *mv = &mvf->mv[lx];
449  const int is_affine = pu->inter_affine_flag;
450  const int is_chroma = !!c_idx;
451  const int idx = av_log2(block_w) - 1;
452  const int8_t *hf = INTER_FILTER_SCALED(refp->scale[0]);
453  const int8_t *vf = INTER_FILTER_SCALED(refp->scale[1]);
454  int denom, wx, ox, x, y, dx, dy, src_height;
455 
456  scaled_ref_pos_and_step(lc, refp, mv, x_off, y_off, c_idx, &x, &y, &dx, &dy);
457  emulated_edge_scaled(lc, &src, &src_stride, &src_height, refp->ref, x, y, dx, dy, block_w, block_h, is_chroma);
458 
459  if (derive_weight_uni(&denom, &wx, &ox, lc, mvf, c_idx)) {
460  fc->vvcdsp.inter.put_uni_w_scaled[is_chroma][idx](dst, dst_stride, src, src_stride, src_height,
461  x, y, dx, dy, block_h, denom, wx, ox, hf, vf, block_w);
462  } else {
463  fc->vvcdsp.inter.put_uni_scaled[is_chroma][idx](dst, dst_stride, src, src_stride, src_height,
464  x, y, dx, dy, block_h, hf, vf, block_w);
465  }
466 }
467 
468 static void mc_bi_scaled(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
469  const VVCRefPic *refp0, const VVCRefPic *refp1, const MvField *mvf,
470  const int x_off, const int y_off, const int block_w, const int block_h, const int c_idx)
471 {
472  const VVCRefPic *refps[] = { refp0, refp1 };
473  int16_t *tmp[] = { lc->tmp, lc->tmp1 };
474 
475  for (int i = L0; i <= L1; i++) {
476  const Mv *mv = mvf->mv + i;
477  const VVCRefPic *refp = refps[i];
478 
479  if (refp->is_scaled)
480  mc_scaled(lc, tmp[i], refp, mv, x_off, y_off, block_w, block_h, c_idx);
481  else
482  mc(lc, tmp[i], refp->ref, mv, x_off, y_off, block_w, block_h, c_idx);
483  }
484  apply_averaging(dst, dst_stride, tmp[L0], tmp[L1], block_w, block_h,
485  lc, mvf, c_idx, lc->cu->pu.dmvr_flag);
486 }
487 
488 static void luma_prof_uni(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
489  const VVCFrame *ref, const MvField *mvf, int x_off, int y_off, const int block_w, const int block_h,
490  const int cb_prof_flag, const int16_t *diff_mv_x, const int16_t *diff_mv_y)
491 {
492  const VVCFrameContext *fc = lc->fc;
493  const uint8_t *src = ref->frame->data[LUMA];
494  ptrdiff_t src_stride = ref->frame->linesize[LUMA];
495  uint16_t *prof_tmp = lc->tmp + PROF_TEMP_OFFSET;
496  const int idx = av_log2(block_w) - 1;
497  const int lx = mvf->pred_flag - PF_L0;
498  const Mv *mv = mvf->mv + lx;
499  const int mx = mv->x & 0xf;
500  const int my = mv->y & 0xf;
503  int denom, wx, ox;
504  const int weight_flag = derive_weight_uni(&denom, &wx, &ox, lc, mvf, LUMA);
505  const int wrap_enabled = fc->ps.pps->r->pps_ref_wraparound_enabled_flag;
506  const int is_chroma = 0;
507 
508  x_off += mv->x >> 4;
509  y_off += mv->y >> 4;
510 
511  MC_EMULATED_EDGE(lc->edge_emu_buffer, &src, &src_stride, x_off, y_off);
512  if (cb_prof_flag) {
513  fc->vvcdsp.inter.put[LUMA][idx][!!my][!!mx](prof_tmp, src, src_stride, AFFINE_MIN_BLOCK_SIZE, hf, vf, AFFINE_MIN_BLOCK_SIZE);
514  fc->vvcdsp.inter.fetch_samples(prof_tmp, src, src_stride, mx, my);
515  if (!weight_flag)
516  fc->vvcdsp.inter.apply_prof_uni(dst, dst_stride, prof_tmp, diff_mv_x, diff_mv_y);
517  else
518  fc->vvcdsp.inter.apply_prof_uni_w(dst, dst_stride, prof_tmp, diff_mv_x, diff_mv_y, denom, wx, ox);
519  } else {
520  if (!weight_flag)
521  fc->vvcdsp.inter.put_uni[LUMA][idx][!!my][!!mx](dst, dst_stride, src, src_stride, block_h, hf, vf, block_w);
522  else
523  fc->vvcdsp.inter.put_uni_w[LUMA][idx][!!my][!!mx](dst, dst_stride, src, src_stride, block_h, denom, wx, ox, hf, vf, block_w);
524  }
525 }
526 
527 static void luma_prof(VVCLocalContext *lc, int16_t *dst, const VVCFrame *ref,
528  const Mv *mv , const int x_off, const int y_off, const int block_w, const int block_h, const int lx)
529 {
530  const VVCFrameContext *fc = lc->fc;
531  const PredictionUnit *pu = &lc->cu->pu;
532  const int mx = mv->x & 0xf;
533  const int my = mv->y & 0xf;
534  const int ox = x_off + (mv->x >> 4);
535  const int oy = y_off + (mv->y >> 4);
536  const int idx = av_log2(block_w) - 1;
537  const int is_chroma = 0;
538  uint16_t *prof_tmp = lc->tmp2 + PROF_TEMP_OFFSET;
539  ptrdiff_t src_stride = ref->frame->linesize[LUMA];
540  const uint8_t *src = ref->frame->data[LUMA];
543  const int wrap_enabled = fc->ps.pps->r->pps_ref_wraparound_enabled_flag;
544 
545  MC_EMULATED_EDGE(lc->edge_emu_buffer, &src, &src_stride, ox, oy);
546  if (!pu->cb_prof_flag[lx]) {
547  fc->vvcdsp.inter.put[LUMA][idx][!!my][!!mx](dst, src, src_stride, block_h, hf, vf, block_w);
548  } else {
549  fc->vvcdsp.inter.put[LUMA][idx][!!my][!!mx](prof_tmp, src, src_stride, AFFINE_MIN_BLOCK_SIZE, hf, vf, AFFINE_MIN_BLOCK_SIZE);
550  fc->vvcdsp.inter.fetch_samples(prof_tmp, src, src_stride, mx, my);
551  fc->vvcdsp.inter.apply_prof(dst, prof_tmp, pu->diff_mv_x[lx], pu->diff_mv_y[lx]);
552  }
553 }
554 
555 static void luma_prof_bi(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
556  const VVCRefPic *ref0, const VVCRefPic *ref1, const MvField *mvf, const int x_off, const int y_off,
557  const int block_w, const int block_h)
558 {
559  const VVCRefPic *refps[] = { ref0, ref1 };
560  int16_t *tmp[] = { lc->tmp, lc->tmp1 };
561 
562  for (int i = L0; i <= L1; i++) {
563  const VVCRefPic *refp = refps[i];
564  const Mv *mv = mvf->mv + i;
565 
566  if (refp->is_scaled)
567  mc_scaled(lc, tmp[i], refp, mv, x_off, y_off, block_w, block_h, LUMA);
568  else
569  luma_prof(lc, tmp[i], refp->ref, mv, x_off, y_off, block_w, block_h, i);
570  }
571 
572  apply_averaging(dst, dst_stride, tmp[L0], tmp[L1], block_w, block_h, lc, mvf, LUMA, 0);
573 }
574 
575 static int pred_get_refs(const VVCLocalContext *lc, VVCRefPic *refp[2], const MvField *mv)
576 {
577  RefPicList *rpl = lc->sc->rpl;
578 
579  for (int mask = PF_L0; mask <= PF_L1; mask++) {
580  if (mv->pred_flag & mask) {
581  const int lx = mask - PF_L0;
582  refp[lx] = rpl[lx].refs + mv->ref_idx[lx];
583  if (!refp[lx]->ref)
584  return AVERROR_INVALIDDATA;
585  }
586  }
587  return 0;
588 }
589 
590 #define POS(c_idx, x, y) \
591  &fc->frame->data[c_idx][((y) >> fc->ps.sps->vshift[c_idx]) * fc->frame->linesize[c_idx] + \
592  (((x) >> fc->ps.sps->hshift[c_idx]) << fc->ps.sps->pixel_shift)]
593 
595 {
596  const VVCFrameContext *fc = lc->fc;
597  const CodingUnit *cu = lc->cu;
598  const PredictionUnit *pu = &cu->pu;
599 
600  const uint8_t angle_idx = ff_vvc_gpm_angle_idx[pu->gpm_partition_idx];
601  const uint8_t weights_idx = ff_vvc_gpm_angle_to_weights_idx[angle_idx];
602  const int w = av_log2(cu->cb_width) - 3;
603  const int h = av_log2(cu->cb_height) - 3;
604  const uint8_t off_x = ff_vvc_gpm_weights_offset_x[pu->gpm_partition_idx][h][w];
605  const uint8_t off_y = ff_vvc_gpm_weights_offset_y[pu->gpm_partition_idx][h][w];
606  const uint8_t mirror_type = ff_vvc_gpm_angle_to_mirror[angle_idx];
607  const uint8_t *weights;
608 
609  const int c_end = fc->ps.sps->r->sps_chroma_format_idc ? 3 : 1;
610 
611  int16_t *tmp[2] = {lc->tmp, lc->tmp1};
612 
613  for (int c_idx = 0; c_idx < c_end; c_idx++) {
614  const int hs = fc->ps.sps->hshift[c_idx];
615  const int vs = fc->ps.sps->vshift[c_idx];
616  const int x = lc->cu->x0 >> hs;
617  const int y = lc->cu->y0 >> vs;
618  const int width = cu->cb_width >> hs;
619  const int height = cu->cb_height >> vs;
620  uint8_t *dst = POS(c_idx, lc->cu->x0, lc->cu->y0);
621  ptrdiff_t dst_stride = fc->frame->linesize[c_idx];
622 
623  int step_x = 1 << hs;
624  int step_y = VVC_GPM_WEIGHT_SIZE << vs;
625  if (!mirror_type) {
626  weights = &ff_vvc_gpm_weights[weights_idx][off_y * VVC_GPM_WEIGHT_SIZE + off_x];
627  } else if (mirror_type == 1) {
628  step_x = -step_x;
629  weights = &ff_vvc_gpm_weights[weights_idx][off_y * VVC_GPM_WEIGHT_SIZE + VVC_GPM_WEIGHT_SIZE - 1- off_x];
630  } else {
631  step_y = -step_y;
632  weights = &ff_vvc_gpm_weights[weights_idx][(VVC_GPM_WEIGHT_SIZE - 1 - off_y) * VVC_GPM_WEIGHT_SIZE + off_x];
633  }
634 
635  for (int i = 0; i < 2; i++) {
636  const MvField *mv = pu->gpm_mv + i;
637  const int lx = mv->pred_flag - PF_L0;
638  VVCRefPic *refp = lc->sc->rpl[lx].refs + mv->ref_idx[lx];
639 
640  if (!refp->ref)
641  return;
642  if (refp->is_scaled)
643  mc_scaled(lc, tmp[i], refp, mv->mv + lx, x, y, width, height, c_idx);
644  else
645  mc(lc, tmp[i], refp->ref, mv->mv + lx, x, y, width, height, c_idx);
646  }
647  fc->vvcdsp.inter.put_gpm(dst, dst_stride, width, height, tmp[0], tmp[1], weights, step_x, step_y);
648  }
649  return;
650 }
651 
652 static int ciip_derive_intra_weight(const VVCLocalContext *lc, const int x0, const int y0,
653  const int width, const int height)
654 {
655  const VVCFrameContext *fc = lc->fc;
656  const VVCSPS *sps = fc->ps.sps;
657  const int x0b = av_zero_extend(x0, sps->ctb_log2_size_y);
658  const int y0b = av_zero_extend(y0, sps->ctb_log2_size_y);
659  const int available_l = lc->ctb_left_flag || x0b;
660  const int available_u = lc->ctb_up_flag || y0b;
661  const int min_pu_width = fc->ps.pps->min_pu_width;
662  int w = 1;
663 
664  if (available_u &&fc->tab.mvf[((y0 - 1) >> MIN_PU_LOG2) * min_pu_width + ((x0 - 1 + width)>> MIN_PU_LOG2)].pred_flag == PF_INTRA)
665  w++;
666 
667  if (available_l && fc->tab.mvf[((y0 - 1 + height)>> MIN_PU_LOG2) * min_pu_width + ((x0 - 1) >> MIN_PU_LOG2)].pred_flag == PF_INTRA)
668  w++;
669 
670  return w;
671 }
672 
673 static void pred_regular(VVCLocalContext *lc, const MvField *mvf, const MvField *orig_mvf,
674  const int x0, const int y0, const int sbw, const int sbh, const int sb_bdof_flag, const int c_start)
675 {
676  const VVCFrameContext *fc = lc->fc;
677  const int c_end = fc->ps.sps->r->sps_chroma_format_idc ? CR : LUMA;
678  VVCRefPic *refp[2];
679 
680  if (pred_get_refs(lc, refp, mvf) < 0)
681  return;
682 
683  for (int c_idx = c_start; c_idx <= c_end; c_idx++) {
684  uint8_t *dst = POS(c_idx, x0, y0);
685  const ptrdiff_t dst_stride = fc->frame->linesize[c_idx];
686  const int hs = fc->ps.sps->hshift[c_idx];
687  const int vs = fc->ps.sps->vshift[c_idx];
688  const int x = x0 >> hs;
689  const int y = y0 >> vs;
690  const int w = sbw >> hs;
691  const int h = sbh >> vs;
692  const int is_luma = !c_idx;
693  const int do_ciip = lc->cu->ciip_flag && (is_luma || (w > 2));
694  uint8_t *inter = do_ciip ? (uint8_t *)lc->ciip_tmp : dst;
695  const ptrdiff_t inter_stride = do_ciip ? (MAX_PB_SIZE * sizeof(uint16_t)) : dst_stride;
696  const int do_bdof = is_luma && sb_bdof_flag;
697 
698  if (mvf->pred_flag != PF_BI) {
699  const int lx = mvf->pred_flag - PF_L0;
700 
701  if (refp[lx]->is_scaled) {
702  mc_uni_scaled(lc, inter, inter_stride, refp[lx], mvf,
703  x, y, w, h, c_idx);
704  } else {
705  mc_uni(lc, inter, inter_stride, refp[lx]->ref, mvf,
706  x, y, w, h, c_idx);
707  }
708  } else {
709  if (refp[L0]->is_scaled || refp[L1]->is_scaled) {
710  mc_bi_scaled(lc, inter, inter_stride, refp[L0], refp[L1], mvf,
711  x, y, w, h, c_idx);
712  } else {
713  mc_bi(lc, inter, inter_stride, refp[L0]->ref, refp[L1]->ref, mvf, orig_mvf,
714  x, y, w, h, c_idx, do_bdof);
715  }
716  }
717  if (do_ciip) {
718  const int intra_weight = ciip_derive_intra_weight(lc, x0, y0, sbw, sbh);
719  fc->vvcdsp.intra.intra_pred(lc, x0, y0, sbw, sbh, c_idx);
720  if (!c_idx && lc->sc->sh.r->sh_lmcs_used_flag)
721  fc->vvcdsp.lmcs.filter(inter, inter_stride, w, h, &fc->ps.lmcs.fwd_lut);
722  fc->vvcdsp.inter.put_ciip(dst, dst_stride, w, h, inter, inter_stride, intra_weight);
723  }
724  }
725 }
726 
727 // 8.5.3.5 Parametric motion vector refinement process
728 static int parametric_mv_refine(const int *sad, const int stride)
729 {
730  const int sad_minus = sad[-stride];
731  const int sad_center = sad[0];
732  const int sad_plus = sad[stride];
733  int dmvc;
734  int denom = (( sad_minus + sad_plus) - (sad_center << 1 ) ) << 3;
735  if (!denom)
736  dmvc = 0;
737  else {
738  if (sad_minus == sad_center)
739  dmvc = -8;
740  else if (sad_plus == sad_center)
741  dmvc = 8;
742  else {
743  int num = ( sad_minus - sad_plus ) * (1 << 4);
744  int sign_num = 0;
745  int quotient = 0;
746  int counter = 3;
747  if (num < 0 ) {
748  num = - num;
749  sign_num = 1;
750  }
751  while (counter > 0) {
752  counter = counter - 1;
753  quotient = quotient << 1;
754  if ( num >= denom ) {
755  num = num - denom;
756  quotient = quotient + 1;
757  }
758  denom = (denom >> 1);
759  }
760  if (sign_num == 1 )
761  dmvc = -quotient;
762  else
763  dmvc = quotient;
764  }
765  }
766  return dmvc;
767 }
768 
769 #define SAD_ARRAY_SIZE 5
770 //8.5.3 Decoder-side motion vector refinement process
771 static void dmvr_mv_refine(VVCLocalContext *lc, MvField *mvf, MvField *orig_mv, int *sb_bdof_flag,
772  const VVCFrame *ref0, const VVCFrame *ref1, const int x_off, const int y_off, const int block_w, const int block_h)
773 {
774  const VVCFrameContext *fc = lc->fc;
775  const int sr_range = 2;
776  const VVCFrame *refs[] = { ref0, ref1 };
777  int16_t *tmp[] = { lc->tmp, lc->tmp1 };
778  int sad[SAD_ARRAY_SIZE][SAD_ARRAY_SIZE];
779  int min_dx, min_dy, min_sad, dx, dy;
780 
781  *orig_mv = *mvf;
782  min_dx = min_dy = dx = dy = 2;
783 
784  for (int i = L0; i <= L1; i++) {
785  const int pred_w = block_w + 2 * sr_range;
786  const int pred_h = block_h + 2 * sr_range;
787  const Mv *mv = mvf->mv + i;
788  const int mx = mv->x & 0xf;
789  const int my = mv->y & 0xf;
790  const int ox = x_off + (mv->x >> 4) - sr_range;
791  const int oy = y_off + (mv->y >> 4) - sr_range;
792  const VVCFrame *ref = refs[i];
793  ptrdiff_t src_stride = ref->frame->linesize[LUMA];
794  const uint8_t *src = ref->frame->data[LUMA];
795  const int wrap_enabled = fc->ps.pps->r->pps_ref_wraparound_enabled_flag;
796 
797  MC_EMULATED_EDGE_BILINEAR(lc->edge_emu_buffer, &src, &src_stride, ox, oy);
798  fc->vvcdsp.inter.dmvr[!!my][!!mx](tmp[i], src, src_stride, pred_h, mx, my, pred_w);
799  }
800 
801  min_sad = fc->vvcdsp.inter.sad(tmp[L0], tmp[L1], dx, dy, block_w, block_h);
802  min_sad -= min_sad >> 2;
803  sad[dy][dx] = min_sad;
804 
805  if (min_sad >= block_w * block_h) {
806  int dmv[2];
807  // 8.5.3.4 Array entry selection process
808  for (dy = 0; dy < SAD_ARRAY_SIZE; dy++) {
809  for (dx = 0; dx < SAD_ARRAY_SIZE; dx++) {
810  if (dx != sr_range || dy != sr_range) {
811  sad[dy][dx] = fc->vvcdsp.inter.sad(lc->tmp, lc->tmp1, dx, dy, block_w, block_h);
812  if (sad[dy][dx] < min_sad) {
813  min_sad = sad[dy][dx];
814  min_dx = dx;
815  min_dy = dy;
816  }
817  }
818  }
819  }
820  dmv[0] = (min_dx - sr_range) * (1 << 4);
821  dmv[1] = (min_dy - sr_range) * (1 << 4);
822  if (min_dx != 0 && min_dx != 4 && min_dy != 0 && min_dy != 4) {
823  dmv[0] += parametric_mv_refine(&sad[min_dy][min_dx], 1);
824  dmv[1] += parametric_mv_refine(&sad[min_dy][min_dx], SAD_ARRAY_SIZE);
825  }
826 
827  for (int i = L0; i <= L1; i++) {
828  Mv *mv = mvf->mv + i;
829  mv->x += (1 - 2 * i) * dmv[0];
830  mv->y += (1 - 2 * i) * dmv[1];
832  }
833  }
834  if (min_sad < 2 * block_w * block_h) {
835  *sb_bdof_flag = 0;
836  }
837 }
838 
839 static void set_dmvr_info(VVCFrameContext *fc, const int x0, const int y0,
840  const int width, const int height, const MvField *mvf)
841 
842 {
843  const VVCPPS *pps = fc->ps.pps;
844 
845  for (int y = y0; y < y0 + height; y += MIN_PU_SIZE) {
846  for (int x = x0; x < x0 + width; x += MIN_PU_SIZE) {
847  const int idx = pps->min_pu_width * (y >> MIN_PU_LOG2) + (x >> MIN_PU_LOG2);
848  fc->ref->tab_dmvr_mvf[idx] = *mvf;
849  }
850  }
851 }
852 
853 static void derive_sb_mv(VVCLocalContext *lc, MvField *mv, MvField *orig_mv, int *sb_bdof_flag,
854  const int x0, const int y0, const int sbw, const int sbh)
855 {
856  VVCFrameContext *fc = lc->fc;
857  const PredictionUnit *pu = &lc->cu->pu;
858 
859  *orig_mv = *mv = *ff_vvc_get_mvf(fc, x0, y0);
860  if (pu->bdof_flag)
861  *sb_bdof_flag = 1;
862  if (pu->dmvr_flag) {
863  VVCRefPic *refp[2];
864  if (pred_get_refs(lc, refp, mv) < 0)
865  return;
866  dmvr_mv_refine(lc, mv, orig_mv, sb_bdof_flag, refp[L0]->ref, refp[L1]->ref, x0, y0, sbw, sbh);
867  set_dmvr_info(fc, x0, y0, sbw, sbh, mv);
868  }
869 }
870 
871 static void pred_regular_blk(VVCLocalContext *lc, const int skip_ciip)
872 {
873  const CodingUnit *cu = lc->cu;
874  PredictionUnit *pu = &lc->cu->pu;
875  const MotionInfo *mi = &pu->mi;
876  MvField mv, orig_mv;
877  int sbw, sbh, sb_bdof_flag = 0;
878 
879  if (cu->ciip_flag && skip_ciip)
880  return;
881 
882  sbw = cu->cb_width / mi->num_sb_x;
883  sbh = cu->cb_height / mi->num_sb_y;
884 
885  for (int sby = 0; sby < mi->num_sb_y; sby++) {
886  for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
887  const int x0 = cu->x0 + sbx * sbw;
888  const int y0 = cu->y0 + sby * sbh;
889 
890  if (cu->ciip_flag)
891  ff_vvc_set_neighbour_available(lc, x0, y0, sbw, sbh);
892 
893  derive_sb_mv(lc, &mv, &orig_mv, &sb_bdof_flag, x0, y0, sbw, sbh);
894  pred_regular(lc, &mv, &orig_mv, x0, y0, sbw, sbh, sb_bdof_flag, LUMA);
895  }
896  }
897 }
898 
899 static void derive_affine_mvc(MvField *mvc, const VVCFrameContext *fc, const MvField *mv,
900  const int x0, const int y0, const int sbw, const int sbh)
901 {
902  const int hs = fc->ps.sps->hshift[1];
903  const int vs = fc->ps.sps->vshift[1];
904  const MvField* mv2 = ff_vvc_get_mvf(fc, x0 + hs * sbw, y0 + vs * sbh);
905  *mvc = *mv;
906 
907  // Due to different pred_flag, one of the motion vectors may have an invalid value.
908  // Cast them to an unsigned type to avoid undefined behavior.
909  mvc->mv[0].x += (unsigned int)mv2->mv[0].x;
910  mvc->mv[0].y += (unsigned int)mv2->mv[0].y;
911  mvc->mv[1].x += (unsigned int)mv2->mv[1].x;
912  mvc->mv[1].y += (unsigned int)mv2->mv[1].y;
913  ff_vvc_round_mv(mvc->mv + 0, 0, 1);
914  ff_vvc_round_mv(mvc->mv + 1, 0, 1);
915 }
916 
918 {
919  const VVCFrameContext *fc = lc->fc;
920  const CodingUnit *cu = lc->cu;
921  const PredictionUnit *pu = &cu->pu;
922  const MotionInfo *mi = &pu->mi;
923  const int x0 = cu->x0;
924  const int y0 = cu->y0;
925  const int sbw = cu->cb_width / mi->num_sb_x;
926  const int sbh = cu->cb_height / mi->num_sb_y;
927  const int hs = fc->ps.sps->hshift[1];
928  const int vs = fc->ps.sps->vshift[1];
929  const int dst_stride = fc->frame->linesize[LUMA];
930 
931  for (int sby = 0; sby < mi->num_sb_y; sby++) {
932  for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
933  const int x = x0 + sbx * sbw;
934  const int y = y0 + sby * sbh;
935 
936  uint8_t *dst0 = POS(0, x, y);
937  const MvField *mv = ff_vvc_get_mvf(fc, x, y);
938  VVCRefPic *refp[2];
939 
940  if (pred_get_refs(lc, refp, mv) < 0)
941  return;
942 
943  if (mi->pred_flag != PF_BI) {
944  const int lx = mi->pred_flag - PF_L0;
945  if (refp[lx]->is_scaled) {
946  mc_uni_scaled(lc, dst0, dst_stride, refp[lx], mv, x, y, sbw, sbh, LUMA);
947  } else {
948  luma_prof_uni(lc, dst0, dst_stride, refp[lx]->ref,
949  mv, x, y, sbw, sbh, pu->cb_prof_flag[lx],
950  pu->diff_mv_x[lx], pu->diff_mv_y[lx]);
951  }
952  } else {
953  luma_prof_bi(lc, dst0, dst_stride, refp[L0], refp[L1], mv, x, y, sbw, sbh);
954  }
955  if (fc->ps.sps->r->sps_chroma_format_idc) {
956  if (!av_zero_extend(sby, vs) && !av_zero_extend(sbx, hs)) {
957  MvField mvc;
958 
959  derive_affine_mvc(&mvc, fc, mv, x, y, sbw, sbh);
960  pred_regular(lc, &mvc, NULL, x, y, sbw << hs, sbh << vs, 0, CB);
961  }
962  }
963 
964  }
965  }
966 }
967 
969 {
970  const VVCFrameContext *fc = lc->fc;
971  const CodingUnit *cu = lc->cu;
972  const PredictionUnit *pu = &cu->pu;
973 
974  if (pu->merge_gpm_flag)
975  pred_gpm_blk(lc);
976  else if (pu->inter_affine_flag)
977  pred_affine_blk(lc);
978  else
979  pred_regular_blk(lc, 1); //intra block is not ready yet, skip ciip
980 
981  if (lc->sc->sh.r->sh_lmcs_used_flag && !cu->ciip_flag) {
982  uint8_t* dst0 = POS(0, cu->x0, cu->y0);
983  fc->vvcdsp.lmcs.filter(dst0, fc->frame->linesize[LUMA], cu->cb_width, cu->cb_height, &fc->ps.lmcs.fwd_lut);
984  }
985 }
986 
987 static int has_inter_luma(const CodingUnit *cu)
988 {
989  return (cu->pred_mode == MODE_INTER || cu->pred_mode == MODE_SKIP) && cu->tree_type != DUAL_TREE_CHROMA;
990 }
991 
992 int ff_vvc_predict_inter(VVCLocalContext *lc, const int rs)
993 {
994  const VVCFrameContext *fc = lc->fc;
995  CodingUnit *cu = fc->tab.cus[rs];
996 
997  while (cu) {
998  lc->cu = cu;
999  if (has_inter_luma(cu))
1000  predict_inter(lc);
1001  cu = cu->next;
1002  }
1003 
1004  return 0;
1005 }
1006 
1008 {
1009  av_assert0(lc->cu->ciip_flag);
1010 
1011  //todo: refact out ciip from pred_regular_blk
1012  pred_regular_blk(lc, 0);
1013 }
1014 
1015 #undef POS
set_dmvr_info
static void set_dmvr_info(VVCFrameContext *fc, const int x0, const int y0, const int width, const int height, const MvField *mvf)
Definition: inter.c:839
VVCSPS
Definition: ps.h:58
ff_vvc_inter_chroma_filters
const int8_t ff_vvc_inter_chroma_filters[VVC_INTER_CHROMA_FILTER_TYPES][VVC_INTER_CHROMA_FACTS][VVC_INTER_CHROMA_TAPS]
Definition: data.c:1877
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
emulated_edge
static void emulated_edge(const VVCLocalContext *lc, uint8_t *dst, const uint8_t **src, ptrdiff_t *src_stride, const VVCFrame *src_frame, int x_sb, int y_sb, int x_off, int y_off, int block_w, int block_h, const int wrap_enabled, const int is_chroma, const int extra_before, const int extra_after)
Definition: inter.c:118
ff_vvc_gpm_angle_to_mirror
const uint8_t ff_vvc_gpm_angle_to_mirror[VVC_GPM_NUM_ANGLES]
Definition: data.c:2095
VVCPPS
Definition: ps.h:92
r
const char * r
Definition: vf_curves.c:127
LUMA
#define LUMA
Definition: filter.c:31
VVCFrame::pps
const VVCPPS * pps
RefStruct reference.
Definition: dec.h:77
SCALE_THRESHOLD_1
#define SCALE_THRESHOLD_1
luma_prof
static void luma_prof(VVCLocalContext *lc, int16_t *dst, const VVCFrame *ref, const Mv *mv, const int x_off, const int y_off, const int block_w, const int block_h, const int lx)
Definition: inter.c:527
MotionInfo
Definition: ctu.h:244
CB
#define CB
Definition: filter.c:32
src1
const pixel * src1
Definition: h264pred_template.c:420
CodingUnit
Definition: hevcdec.h:290
mv
static const int8_t mv[256][2]
Definition: 4xm.c:81
PredictionUnit::gpm_partition_idx
uint8_t gpm_partition_idx
Definition: ctu.h:266
VVCLocalContext::tmp
int16_t tmp[MAX_PB_SIZE *MAX_PB_SIZE]
Definition: ctu.h:394
mask
int mask
Definition: mediacodecdec_common.c:154
IS_P
#define IS_P(rsh)
Definition: ps.h:39
ff_vvc_predict_inter
int ff_vvc_predict_inter(VVCLocalContext *lc, const int rs)
Loop entire CTU to predict all inter coding blocks.
Definition: inter.c:992
data.h
VVCLocalContext::ciip_tmp
uint8_t ciip_tmp[MAX_PB_SIZE *MAX_PB_SIZE *2]
Definition: ctu.h:397
VVCRefPic
Definition: dec.h:47
VVCLocalContext::sc
SliceContext * sc
Definition: ctu.h:445
b
#define b
Definition: input.c:42
Mv::y
int16_t y
vertical component of motion vector
Definition: hevcdec.h:305
VVCSH::r
const H266RawSliceHeader * r
RefStruct reference.
Definition: ps.h:239
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
VVCRect::t
int t
Definition: ctu.h:481
RefPicList
Definition: hevcdec.h:194
derive_sb_mv
static void derive_sb_mv(VVCLocalContext *lc, MvField *mv, MvField *orig_mv, int *sb_bdof_flag, const int x0, const int y0, const int sbw, const int sbh)
Definition: inter.c:853
subpic_get_rect
static void subpic_get_rect(VVCRect *r, const VVCFrame *src_frame, const int subpic_idx, const int is_chroma)
Definition: inter.c:33
PF_INTRA
@ PF_INTRA
Definition: hevcdec.h:118
INTER_FILTER
#define INTER_FILTER(t, frac)
Definition: inter.c:253
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:448
VVCRefPic::ref
struct VVCFrame * ref
Definition: dec.h:48
MODE_SKIP
@ MODE_SKIP
Definition: hevcdec.h:108
MIN_PU_LOG2
#define MIN_PU_LOG2
Definition: dec.h:42
mx
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t mx
Definition: dsp.h:57
MC_EMULATED_EDGE_DMVR
#define MC_EMULATED_EDGE_DMVR(dst, src, src_stride, x_sb, y_sb, x_off, y_off)
Definition: inter.c:191
PredictionUnit::gpm_mv
MvField gpm_mv[2]
Definition: ctu.h:267
VVCLocalContext::fc
VVCFrameContext * fc
Definition: ctu.h:446
VVCSH::pwt
PredWeightTable pwt
Definition: ps.h:247
PredictionUnit
Definition: hevcdec.h:323
wrap
#define wrap(func)
Definition: neontest.h:65
MODE_INTER
@ MODE_INTER
Definition: hevcdec.h:106
IS_B
#define IS_B(rsh)
Definition: ps.h:40
VVCLocalContext::tmp1
int16_t tmp1[MAX_PB_SIZE *MAX_PB_SIZE]
Definition: ctu.h:395
apply_averaging
static void apply_averaging(uint8_t *dst, const ptrdiff_t dst_stride, const int16_t *src0, const int16_t *src1, int width, int height, const VVCLocalContext *lc, const MvField *mvf, const int c_idx, const int dmvr_flag)
Definition: inter.c:220
derive_weight_uni
static int derive_weight_uni(int *denom, int *wx, int *ox, const VVCLocalContext *lc, const MvField *mvf, const int c_idx)
Definition: inter.c:200
SCALED_INT
#define SCALED_INT(pos)
Definition: ctu.h:65
SliceContext::rpl
RefPicList * rpl
Definition: dec.h:118
VVCRect
Definition: ctu.h:479
SCALED_REF
#define SCALED_REF(ref_sb, offset, shift)
Definition: inter.c:381
bcw_w_lut
static const int bcw_w_lut[]
Definition: inter.c:31
CodingUnit::cb_width
int cb_width
Definition: ctu.h:291
INTER_FILTER_SCALED
#define INTER_FILTER_SCALED(scale)
Definition: inter.c:377
CodingUnit::pu
PredictionUnit pu
Definition: ctu.h:338
RefPicList::refs
VVCRefPic refs[VVC_MAX_REF_ENTRIES]
Definition: dec.h:58
ff_vvc_clip_mv
void ff_vvc_clip_mv(Mv *mv)
Definition: mvs.c:1900
PROF_TEMP_OFFSET
#define PROF_TEMP_OFFSET
Definition: inter.c:30
SCALED_CHROMA_ADDIN
#define SCALED_CHROMA_ADDIN(scale, collocated_flag)
Definition: inter.c:379
emulated_half
static void emulated_half(const VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, const ptrdiff_t src_stride, const int ps, int x_off, int y_off, const int block_w, const int block_h, const VVCRect *subpic, const VVCRect *half_sb, const int dmvr_clip)
Definition: inter.c:91
mi
#define mi
Definition: vf_colormatrix.c:106
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:494
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
VVCSH
Definition: ps.h:238
VVCLocalContext::edge_emu_buffer
uint8_t edge_emu_buffer[EDGE_EMU_BUFFER_STRIDE *EDGE_EMU_BUFFER_STRIDE *2]
Definition: ctu.h:393
PredWeightTable
Definition: ps.h:137
CodingUnit::tree_type
VVCTreeType tree_type
Definition: ctu.h:288
ff_vvc_gpm_weights_offset_x
const uint8_t ff_vvc_gpm_weights_offset_x[VVC_GPM_NUM_PARTITION][4][4]
Definition: data.c:2106
dmvr_mv_refine
static void dmvr_mv_refine(VVCLocalContext *lc, MvField *mvf, MvField *orig_mv, int *sb_bdof_flag, const VVCFrame *ref0, const VVCFrame *ref1, const int x_off, const int y_off, const int block_w, const int block_h)
Definition: inter.c:771
PredictionUnit::bdof_flag
uint8_t bdof_flag
Definition: ctu.h:275
has_inter_luma
static int has_inter_luma(const CodingUnit *cu)
Definition: inter.c:987
SCALE_THRESHOLD_2
#define SCALE_THRESHOLD_2
sb_set_lr
static void sb_set_lr(VVCRect *sb, const int l, const int r)
Definition: inter.c:107
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
my
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t my
Definition: dsp.h:57
H266RawSliceHeader::sh_lmcs_used_flag
uint8_t sh_lmcs_used_flag
Definition: cbs_h266.h:794
inter.h
SAD_ARRAY_SIZE
#define SAD_ARRAY_SIZE
Definition: inter.c:769
NULL
#define NULL
Definition: coverity.c:32
mc_scaled
static void mc_scaled(VVCLocalContext *lc, int16_t *dst, const VVCRefPic *refp, const Mv *mv, int x_off, int y_off, const int block_w, const int block_h, const int c_idx)
Definition: inter.c:421
SCALED_STEP
#define SCALED_STEP(scale)
Definition: inter.c:382
derive_affine_mvc
static void derive_affine_mvc(MvField *mvc, const VVCFrameContext *fc, const MvField *mv, const int x0, const int y0, const int sbw, const int sbh)
Definition: inter.c:899
VVCLocalContext
Definition: ctu.h:384
pred_h
static void FUNC() pred_h(uint8_t *_src, const uint8_t *_left, const int w, const int h, const ptrdiff_t stride)
Definition: intra_template.c:877
H266RawSliceHeader::curr_subpic_idx
uint16_t curr_subpic_idx
CurrSubpicIdx.
Definition: cbs_h266.h:837
mc_bi_scaled
static void mc_bi_scaled(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const VVCRefPic *refp0, const VVCRefPic *refp1, const MvField *mvf, const int x_off, const int y_off, const int block_w, const int block_h, const int c_idx)
Definition: inter.c:468
L0
#define L0
Definition: hevcdec.h:56
scaled_ref_pos_and_step
static void scaled_ref_pos_and_step(const VVCLocalContext *lc, const VVCRefPic *refp, const Mv *mv, const int x_off, const int y_off, const int c_idx, int *x, int *y, int *dx, int *dy)
Definition: inter.c:384
MC_EMULATED_EDGE
#define MC_EMULATED_EDGE(dst, src, src_stride, x_off, y_off)
Definition: inter.c:187
ff_vvc_round_mv
void ff_vvc_round_mv(Mv *mv, const int lshift, const int rshift)
Definition: mvs.c:1888
VVCRefPic::is_scaled
int is_scaled
RprConstraintsActiveFlag.
Definition: dec.h:53
Mv::x
int16_t x
horizontal component of motion vector
Definition: hevcdec.h:304
PF_BI
@ PF_BI
Definition: hevcdec.h:121
predict_inter
static void predict_inter(VVCLocalContext *lc)
Definition: inter.c:968
ff_vvc_inter_luma_filters
const int8_t ff_vvc_inter_luma_filters[VVC_INTER_LUMA_FILTER_TYPES][VVC_INTER_LUMA_FACTS][VVC_INTER_LUMA_TAPS]
Definition: data.c:1735
MIN_PU_SIZE
#define MIN_PU_SIZE
Definition: ctu.h:43
clip_to_subpic
static void clip_to_subpic(int *x_off, int *y_off, int *pic_width, int *pic_height, const VVCRect *subpic, const VVCRect *sb, const int dmvr_clip)
Definition: inter.c:47
pred_affine_blk
static void pred_affine_blk(VVCLocalContext *lc)
Definition: inter.c:917
mvs.h
height
#define height
Definition: dsp.h:89
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
MotionInfo::hpel_if_idx
uint8_t hpel_if_idx
hpelIfIdx
Definition: ctu.h:247
PredictionUnit::merge_gpm_flag
uint8_t merge_gpm_flag
Definition: ctu.h:265
PredictionUnit::cb_prof_flag
int cb_prof_flag[2]
Definition: ctu.h:279
VVC_GPM_WEIGHT_SIZE
#define VVC_GPM_WEIGHT_SIZE
Definition: data.h:71
MvField
Definition: hevcdec.h:308
refs.h
frame.h
pred_gpm_blk
static void pred_gpm_blk(VVCLocalContext *lc)
Definition: inter.c:594
PF_L1
@ PF_L1
Definition: hevcdec.h:120
AFFINE_MIN_BLOCK_SIZE
#define AFFINE_MIN_BLOCK_SIZE
Definition: ctu.h:69
VVCLocalContext::ctb_up_flag
uint8_t ctb_up_flag
Definition: ctu.h:386
pred_regular
static void pred_regular(VVCLocalContext *lc, const MvField *mvf, const MvField *orig_mvf, const int x0, const int y0, const int sbw, const int sbh, const int sb_bdof_flag, const int c_start)
Definition: inter.c:673
PredictionUnit::diff_mv_x
int16_t diff_mv_x[2][AFFINE_MIN_BLOCK_SIZE *AFFINE_MIN_BLOCK_SIZE]
diffMvLX
Definition: ctu.h:277
VVCRect::l
int l
Definition: ctu.h:480
VVCFrame
Definition: dec.h:73
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
ff_vvc_predict_ciip
void ff_vvc_predict_ciip(VVCLocalContext *lc)
CIIP(Combined Inter-Intra Prediction) for a coding block.
Definition: inter.c:1007
av_zero_extend
#define av_zero_extend
Definition: common.h:151
MC_EMULATED_EDGE_BILINEAR
#define MC_EMULATED_EDGE_BILINEAR(dst, src, src_stride, x_off, y_off)
Definition: inter.c:195
MvField::pred_flag
int8_t pred_flag
Definition: hevcdec.h:311
emulated_edge_no_wrap
static void emulated_edge_no_wrap(const VVCLocalContext *lc, uint8_t *dst, const uint8_t **src, ptrdiff_t *src_stride, int x_off, int y_off, const int block_w, const int block_h, const int extra_before, const int extra_after, const VVCRect *subpic, const VVCRect *sb, const int dmvr_clip)
Definition: inter.c:60
emulated_edge_scaled
static void emulated_edge_scaled(VVCLocalContext *lc, const uint8_t **src, ptrdiff_t *src_stride, int *src_height, const VVCFrame *ref, const int x, const int y, const int dx, const int dy, const int w, const int h, const int is_chroma)
Definition: inter.c:405
PredictionUnit::mi
MotionInfo mi
Definition: ctu.h:271
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:68
CR
#define CR
Definition: filter.c:33
parametric_mv_refine
static int parametric_mv_refine(const int *sad, const int stride)
Definition: inter.c:728
mc_bi
static void mc_bi(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const VVCFrame *ref0, const VVCFrame *ref1, const MvField *mvf, const MvField *orig_mv, const int x_off, const int y_off, const int block_w, const int block_h, const int c_idx, const int sb_bdof_flag)
Definition: inter.c:315
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ff_vvc_gpm_angle_idx
const uint8_t ff_vvc_gpm_angle_idx[VVC_GPM_NUM_PARTITION]
Definition: data.c:2077
pred_get_refs
static int pred_get_refs(const VVCLocalContext *lc, VVCRefPic *refp[2], const MvField *mv)
Definition: inter.c:575
weights
static const int weights[]
Definition: hevc_pel.c:32
mc_uni_scaled
static void mc_uni_scaled(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const VVCRefPic *refp, const MvField *mvf, const int x_off, const int y_off, const int block_w, const int block_h, const int c_idx)
Definition: inter.c:440
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
PF_L0
@ PF_L0
Definition: hevcdec.h:119
EDGE_EMU_BUFFER_STRIDE
#define EDGE_EMU_BUFFER_STRIDE
Definition: hevcdec.h:66
POS
#define POS(c_idx, x, y)
Definition: inter.c:590
CodingUnit::x0
int x0
Definition: ctu.h:289
hf
uint8_t ptrdiff_t const uint8_t ptrdiff_t int const int8_t * hf
Definition: dsp.h:258
VVCRect::b
int b
Definition: ctu.h:483
VVCLocalContext::cu
CodingUnit * cu
Definition: ctu.h:429
MAX_PB_SIZE
#define MAX_PB_SIZE
Definition: dsp.h:32
PredictionUnit::dmvr_flag
uint8_t dmvr_flag
Definition: ctu.h:274
inter_filter_scaled
static const int8_t * inter_filter_scaled(const int scale, const int is_chroma, const int is_affine)
Definition: inter.c:362
VVCFrame::frame
struct AVFrame * frame
Definition: dec.h:74
ff_vvc_gpm_weights
const uint8_t ff_vvc_gpm_weights[6][VVC_GPM_WEIGHT_SIZE *VVC_GPM_WEIGHT_SIZE]
Definition: data.c:2880
sps
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
Definition: cbs_h264_syntax_template.c:260
PredictionUnit::inter_affine_flag
uint8_t inter_affine_flag
Definition: ctu.h:260
ff_vvc_get_mvf
MvField * ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0)
Definition: mvs.c:1960
CodingUnit::cb_height
int cb_height
Definition: ctu.h:292
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
ff_vvc_set_neighbour_available
void ff_vvc_set_neighbour_available(VVCLocalContext *lc, const int x0, const int y0, const int w, const int h)
Definition: ctu.c:2872
DUAL_TREE_CHROMA
@ DUAL_TREE_CHROMA
Definition: ctu.h:170
ciip_derive_intra_weight
static int ciip_derive_intra_weight(const VVCLocalContext *lc, const int x0, const int y0, const int width, const int height)
Definition: inter.c:652
CodingUnit::pred_mode
enum PredMode pred_mode
PredMode.
Definition: hevcdec.h:294
VVCRect::r
int r
Definition: ctu.h:482
VVCLocalContext::tmp2
int16_t tmp2[MAX_PB_SIZE *MAX_PB_SIZE]
Definition: ctu.h:396
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
pps
uint64_t pps
Definition: dovi_rpuenc.c:36
src0
const pixel *const src0
Definition: h264pred_template.c:419
PredictionUnit::diff_mv_y
int16_t diff_mv_y[2][AFFINE_MIN_BLOCK_SIZE *AFFINE_MIN_BLOCK_SIZE]
diffMvLX
Definition: ctu.h:278
sb_wrap
static void sb_wrap(VVCRect *sb, const int wrap)
Definition: inter.c:113
CodingUnit::next
struct CodingUnit * next
RefStruct reference.
Definition: ctu.h:340
MvField::mv
Mv mv[2]
mvL0, vvL1
Definition: hevcdec.h:309
Mv
Definition: hevcdec.h:303
MvField::ref_idx
int8_t ref_idx[2]
refIdxL0, refIdxL1
Definition: hevcdec.h:310
w
uint8_t w
Definition: llvidencdsp.c:39
pred_regular_blk
static void pred_regular_blk(VVCLocalContext *lc, const int skip_ciip)
Definition: inter.c:871
luma_prof_bi
static void luma_prof_bi(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const VVCRefPic *ref0, const VVCRefPic *ref1, const MvField *mvf, const int x_off, const int y_off, const int block_w, const int block_h)
Definition: inter.c:555
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:278
ff_vvc_gpm_weights_offset_y
const uint8_t ff_vvc_gpm_weights_offset_y[VVC_GPM_NUM_PARTITION][4][4]
Definition: data.c:2493
SliceContext::sh
VVCSH sh
Definition: dec.h:115
SCALED_REF_SB
#define SCALED_REF_SB(off, scaling_off, ref_mv, scale, add, shift)
Definition: inter.c:380
VVCFrameContext
Definition: dec.h:122
MvField::bcw_idx
uint8_t bcw_idx
bcwIdx
Definition: ctu.h:206
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:472
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
h
h
Definition: vp9dsp_template.c:2070
stride
#define stride
Definition: h264pred_template.c:536
width
#define width
Definition: dsp.h:89
VVC_INTER_LUMA_FILTER_TYPE_AFFINE
#define VVC_INTER_LUMA_FILTER_TYPE_AFFINE
Definition: data.h:49
vf
uint8_t ptrdiff_t const uint8_t ptrdiff_t int const int8_t const int8_t * vf
Definition: dsp.h:258
CodingUnit::ciip_flag
uint8_t ciip_flag
Definition: ctu.h:312
ff_vvc_gpm_angle_to_weights_idx
const uint8_t ff_vvc_gpm_angle_to_weights_idx[VVC_GPM_NUM_ANGLES]
Definition: data.c:2100
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
mc_uni
static void mc_uni(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const VVCFrame *ref, const MvField *mvf, int x_off, int y_off, const int block_w, const int block_h, const int c_idx)
Definition: inter.c:280
VVCFrame::sps
const VVCSPS * sps
RefStruct reference.
Definition: dec.h:76
src
#define src
Definition: vp8dsp.c:248
VVCLocalContext::ctb_left_flag
uint8_t ctb_left_flag
Definition: ctu.h:385
luma_prof_uni
static void luma_prof_uni(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const VVCFrame *ref, const MvField *mvf, int x_off, int y_off, const int block_w, const int block_h, const int cb_prof_flag, const int16_t *diff_mv_x, const int16_t *diff_mv_y)
Definition: inter.c:488
VVCRefPic::scale
int scale[2]
RefPicScale[].
Definition: dec.h:54
CodingUnit::y0
int y0
Definition: ctu.h:290
mc
static void mc(VVCLocalContext *lc, int16_t *dst, const VVCFrame *ref, const Mv *mv, int x_off, int y_off, const int block_w, const int block_h, const int c_idx)
Definition: inter.c:255