FFmpeg
vvc_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 "vvc_data.h"
25 #include "vvc_inter.h"
26 #include "vvc_mvs.h"
27 #include "vvc_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_offset(int *x_off, int *y_off,
34  const VVCSPS *sps, const VVCPPS *pps, const int subpic_idx, const int is_luma)
35 {
36  *x_off -= pps->subpic_x[subpic_idx] >> sps->hshift[!is_luma];
37  *y_off -= pps->subpic_y[subpic_idx] >> sps->vshift[!is_luma];
38 }
39 
40 static void subpic_width_height(int *pic_width, int *pic_height,
41  const VVCSPS *sps, const VVCPPS *pps, const int subpic_idx, const int is_luma)
42 {
43  *pic_width = pps->subpic_width[subpic_idx] >> sps->hshift[!is_luma];
44  *pic_height = pps->subpic_height[subpic_idx] >> sps->vshift[!is_luma];
45 }
46 
47 static int emulated_edge(const VVCLocalContext *lc, uint8_t *dst, const uint8_t **src, ptrdiff_t *src_stride,
48  int x_off, int y_off, const int block_w, const int block_h, const int is_luma)
49 {
50  const VVCFrameContext *fc = lc->fc;
51  const VVCSPS *sps = fc->ps.sps;
52  const VVCPPS *pps = fc->ps.pps;
53  const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
54  const int extra_before = is_luma ? LUMA_EXTRA_BEFORE : CHROMA_EXTRA_BEFORE;
55  const int extra_after = is_luma ? LUMA_EXTRA_AFTER : CHROMA_EXTRA_AFTER;
56  const int extra = is_luma ? LUMA_EXTRA : CHROMA_EXTRA;
57  int pic_width, pic_height;
58 
59  subpic_offset(&x_off, &y_off, sps, pps, subpic_idx, is_luma);
60  subpic_width_height(&pic_width, &pic_height, sps, pps, subpic_idx, is_luma);
61 
62  if (x_off < extra_before || y_off < extra_before ||
63  x_off >= pic_width - block_w - extra_after ||
64  y_off >= pic_height - block_h - extra_after) {
65  const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << fc->ps.sps->pixel_shift;
66  int offset = extra_before * *src_stride + (extra_before << fc->ps.sps->pixel_shift);
67  int buf_offset = extra_before * edge_emu_stride + (extra_before << fc->ps.sps->pixel_shift);
68 
69  fc->vdsp.emulated_edge_mc(dst, *src - offset, edge_emu_stride, *src_stride,
70  block_w + extra, block_h + extra, x_off - extra_before, y_off - extra_before,
71  pic_width, pic_height);
72 
73  *src = dst + buf_offset;
74  *src_stride = edge_emu_stride;
75  return 1;
76  }
77  return 0;
78 }
79 
80 static void emulated_edge_dmvr(const VVCLocalContext *lc, uint8_t *dst, const uint8_t **src, ptrdiff_t *src_stride,
81  int x_sb, int y_sb, int x_off, int y_off, const int block_w, const int block_h, const int is_luma)
82 {
83  const VVCFrameContext *fc = lc->fc;
84  const VVCSPS *sps = fc->ps.sps;
85  const VVCPPS *pps = fc->ps.pps;
86  const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
87  const int extra_before = is_luma ? LUMA_EXTRA_BEFORE : CHROMA_EXTRA_BEFORE;
88  const int extra_after = is_luma ? LUMA_EXTRA_AFTER : CHROMA_EXTRA_AFTER;
89  const int extra = is_luma ? LUMA_EXTRA : CHROMA_EXTRA;
90  int pic_width, pic_height;
91 
92  subpic_offset(&x_off, &y_off, sps, pps, subpic_idx, is_luma);
93  subpic_offset(&x_sb, &y_sb, sps, pps, subpic_idx, is_luma);
94  subpic_width_height(&pic_width, &pic_height, sps, pps, subpic_idx, is_luma);
95 
96  if (x_off < extra_before || y_off < extra_before ||
97  x_off >= pic_width - block_w - extra_after ||
98  y_off >= pic_height - block_h - extra_after||
99  (x_off != x_sb || y_off != y_sb)) {
100  const int ps = fc->ps.sps->pixel_shift;
101  const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << ps;
102  const int offset = extra_before * *src_stride + (extra_before << ps);
103  const int buf_offset = extra_before * edge_emu_stride + (extra_before << ps);
104 
105  const int start_x = FFMIN(FFMAX(x_sb - extra_before, 0), pic_width - 1);
106  const int start_y = FFMIN(FFMAX(y_sb - extra_before, 0), pic_height - 1);
107  const int width = FFMAX(FFMIN(pic_width, x_sb + block_w + extra_after) - start_x, 1);
108  const int height = FFMAX(FFMIN(pic_height, y_sb + block_h + extra_after) - start_y, 1);
109 
110  fc->vdsp.emulated_edge_mc(dst, *src - offset, edge_emu_stride, *src_stride, block_w + extra, block_h + extra,
111  x_off - start_x - extra_before, y_off - start_y - extra_before, width, height);
112 
113  *src = dst + buf_offset;
114  *src_stride = edge_emu_stride;
115  }
116 }
117 
118 static void emulated_edge_bilinear(const VVCLocalContext *lc, uint8_t *dst, const uint8_t **src, ptrdiff_t *src_stride,
119  int x_off, int y_off, const int block_w, const int block_h)
120 {
121  const VVCFrameContext *fc = lc->fc;
122  const VVCSPS *sps = fc->ps.sps;
123  const VVCPPS *pps = fc->ps.pps;
124  const int subpic_idx = lc->sc->sh.r->curr_subpic_idx;
125  int pic_width, pic_height;
126 
127  subpic_offset(&x_off, &y_off, sps, pps, subpic_idx, 1);
128  subpic_width_height(&pic_width, &pic_height, sps, pps, subpic_idx, 1);
129 
130  if (x_off < BILINEAR_EXTRA_BEFORE || y_off < BILINEAR_EXTRA_BEFORE ||
131  x_off >= pic_width - block_w - BILINEAR_EXTRA_AFTER ||
132  y_off >= pic_height - block_h - BILINEAR_EXTRA_AFTER) {
133  const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << fc->ps.sps->pixel_shift;
134  const int offset = BILINEAR_EXTRA_BEFORE * *src_stride + (BILINEAR_EXTRA_BEFORE << fc->ps.sps->pixel_shift);
135  const int buf_offset = BILINEAR_EXTRA_BEFORE * edge_emu_stride + (BILINEAR_EXTRA_BEFORE << fc->ps.sps->pixel_shift);
136 
137  fc->vdsp.emulated_edge_mc(dst, *src - offset, edge_emu_stride, *src_stride, block_w + BILINEAR_EXTRA, block_h + BILINEAR_EXTRA,
138  x_off - BILINEAR_EXTRA_BEFORE, y_off - BILINEAR_EXTRA_BEFORE, pic_width, pic_height);
139 
140  *src = dst + buf_offset;
141  *src_stride = edge_emu_stride;
142  }
143 }
144 
145 
146 #define EMULATED_EDGE_LUMA(dst, src, src_stride, x_off, y_off) \
147  emulated_edge(lc, dst, src, src_stride, x_off, y_off, block_w, block_h, 1)
148 
149 #define EMULATED_EDGE_CHROMA(dst, src, src_stride, x_off, y_off) \
150  emulated_edge(lc, dst, src, src_stride, x_off, y_off, block_w, block_h, 0)
151 
152 #define EMULATED_EDGE_DMVR_LUMA(dst, src, src_stride, x_sb, y_sb, x_off, y_off) \
153  emulated_edge_dmvr(lc, dst, src, src_stride, x_sb, y_sb, x_off, y_off, block_w, block_h, 1)
154 
155 #define EMULATED_EDGE_DMVR_CHROMA(dst, src, src_stride, x_sb, y_sb, x_off, y_off) \
156  emulated_edge_dmvr(lc, dst, src, src_stride, x_sb, y_sb, x_off, y_off, block_w, block_h, 0)
157 
158 #define EMULATED_EDGE_BILINEAR(dst, src, src_stride, x_off, y_off) \
159  emulated_edge_bilinear(lc, dst, src, src_stride, x_off, y_off, pred_w, pred_h)
160 
161 // part of 8.5.6.6 Weighted sample prediction process
162 static int derive_weight_uni(int *denom, int *wx, int *ox,
163  const VVCLocalContext *lc, const MvField *mvf, const int c_idx)
164 {
165  const VVCFrameContext *fc = lc->fc;
166  const VVCPPS *pps = fc->ps.pps;
167  const VVCSH *sh = &lc->sc->sh;
168  const int weight_flag = (IS_P(sh->r) && pps->r->pps_weighted_pred_flag) ||
169  (IS_B(sh->r) && pps->r->pps_weighted_bipred_flag);
170  if (weight_flag) {
171  const int lx = mvf->pred_flag - PF_L0;
172  const PredWeightTable *w = pps->r->pps_wp_info_in_ph_flag ? &fc->ps.ph.pwt : &sh->pwt;
173 
174  *denom = w->log2_denom[c_idx > 0];
175  *wx = w->weight[lx][c_idx][mvf->ref_idx[lx]];
176  *ox = w->offset[lx][c_idx][mvf->ref_idx[lx]];
177  }
178  return weight_flag;
179 }
180 
181 // part of 8.5.6.6 Weighted sample prediction process
182 static int derive_weight(int *denom, int *w0, int *w1, int *o0, int *o1,
183  const VVCLocalContext *lc, const MvField *mvf, const int c_idx, const int dmvr_flag)
184 {
185  const VVCFrameContext *fc = lc->fc;
186  const VVCPPS *pps = fc->ps.pps;
187  const VVCSH *sh = &lc->sc->sh;
188  const int bcw_idx = mvf->bcw_idx;
189  const int weight_flag = (IS_P(sh->r) && pps->r->pps_weighted_pred_flag) ||
190  (IS_B(sh->r) && pps->r->pps_weighted_bipred_flag && !dmvr_flag);
191  if ((!weight_flag && !bcw_idx) || (bcw_idx && lc->cu->ciip_flag))
192  return 0;
193 
194  if (bcw_idx) {
195  *denom = 2;
196  *w1 = bcw_w_lut[bcw_idx];
197  *w0 = 8 - *w1;
198  *o0 = *o1 = 0;
199  } else {
200  const VVCPPS *pps = fc->ps.pps;
201  const PredWeightTable *w = pps->r->pps_wp_info_in_ph_flag ? &fc->ps.ph.pwt : &sh->pwt;
202 
203  *denom = w->log2_denom[c_idx > 0];
204  *w0 = w->weight[L0][c_idx][mvf->ref_idx[L0]];
205  *w1 = w->weight[L1][c_idx][mvf->ref_idx[L1]];
206  *o0 = w->offset[L0][c_idx][mvf->ref_idx[L0]];
207  *o1 = w->offset[L1][c_idx][mvf->ref_idx[L1]];
208  }
209  return 1;
210 }
211 
212 static void luma_mc(VVCLocalContext *lc, int16_t *dst, const AVFrame *ref, const Mv *mv,
213  int x_off, int y_off, const int block_w, const int block_h)
214 {
215  const VVCFrameContext *fc = lc->fc;
216  const uint8_t *src = ref->data[0];
217  ptrdiff_t src_stride = ref->linesize[0];
218  const int idx = av_log2(block_w) - 1;
219  const int mx = mv->x & 0xf;
220  const int my = mv->y & 0xf;
221  const int8_t *hf = ff_vvc_inter_luma_filters[0][mx];
222  const int8_t *vf = ff_vvc_inter_luma_filters[0][my];
223 
224  x_off += mv->x >> 4;
225  y_off += mv->y >> 4;
226  src += y_off * src_stride + (x_off * (1 << fc->ps.sps->pixel_shift));
227 
228  EMULATED_EDGE_LUMA(lc->edge_emu_buffer, &src, &src_stride, x_off, y_off);
229 
230  fc->vvcdsp.inter.put[LUMA][idx][!!my][!!mx](dst, src, src_stride, block_h, hf, vf, block_w);
231 }
232 
233 static void chroma_mc(VVCLocalContext *lc, int16_t *dst, const AVFrame *ref, const Mv *mv,
234  int x_off, int y_off, const int block_w, const int block_h, const int c_idx)
235 {
236  const VVCFrameContext *fc = lc->fc;
237  const uint8_t *src = ref->data[c_idx];
238  ptrdiff_t src_stride = ref->linesize[c_idx];
239  int hs = fc->ps.sps->hshift[c_idx];
240  int vs = fc->ps.sps->vshift[c_idx];
241  const int idx = av_log2(block_w) - 1;
242  const intptr_t mx = av_mod_uintp2(mv->x, 4 + hs) << (1 - hs);
243  const intptr_t my = av_mod_uintp2(mv->y, 4 + vs) << (1 - vs);
244  const int8_t *hf = ff_vvc_inter_chroma_filters[0][mx];
245  const int8_t *vf = ff_vvc_inter_chroma_filters[0][my];
246 
247  x_off += mv->x >> (4 + hs);
248  y_off += mv->y >> (4 + vs);
249  src += y_off * src_stride + (x_off * (1 << fc->ps.sps->pixel_shift));
250 
251  EMULATED_EDGE_CHROMA(lc->edge_emu_buffer, &src, &src_stride, x_off, y_off);
252  fc->vvcdsp.inter.put[CHROMA][idx][!!my][!!mx](dst, src, src_stride, block_h, hf, vf, block_w);
253 }
254 
255 static void luma_mc_uni(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
256  const AVFrame *ref, const MvField *mvf, int x_off, int y_off, const int block_w, const int block_h,
257  const int hf_idx, const int vf_idx)
258 {
259  const VVCFrameContext *fc = lc->fc;
260  const int lx = mvf->pred_flag - PF_L0;
261  const Mv *mv = mvf->mv + lx;
262  const uint8_t *src = ref->data[0];
263  ptrdiff_t src_stride = ref->linesize[0];
264  const int idx = av_log2(block_w) - 1;
265  const int mx = mv->x & 0xf;
266  const int my = mv->y & 0xf;
267  const int8_t *hf = ff_vvc_inter_luma_filters[hf_idx][mx];
268  const int8_t *vf = ff_vvc_inter_luma_filters[vf_idx][my];
269  int denom, wx, ox;
270 
271  x_off += mv->x >> 4;
272  y_off += mv->y >> 4;
273  src += y_off * src_stride + (x_off * (1 << fc->ps.sps->pixel_shift));
274 
275  EMULATED_EDGE_LUMA(lc->edge_emu_buffer, &src, &src_stride, x_off, y_off);
276 
277  if (derive_weight_uni(&denom, &wx, &ox, lc, mvf, LUMA)) {
278  fc->vvcdsp.inter.put_uni_w[LUMA][idx][!!my][!!mx](dst, dst_stride, src, src_stride,
279  block_h, denom, wx, ox, hf, vf, block_w);
280  } else {
281  fc->vvcdsp.inter.put_uni[LUMA][idx][!!my][!!mx](dst, dst_stride, src, src_stride,
282  block_h, hf, vf, block_w);
283  }
284 }
285 
286 static void luma_mc_bi(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
287  const AVFrame *ref0, const Mv *mv0, const int x_off, const int y_off, const int block_w, const int block_h,
288  const AVFrame *ref1, const Mv *mv1, const MvField *mvf, const int hf_idx, const int vf_idx,
289  const MvField *orig_mv, const int sb_bdof_flag)
290 {
291  const VVCFrameContext *fc = lc->fc;
292  const PredictionUnit *pu = &lc->cu->pu;
293  const int idx = av_log2(block_w) - 1;
294  const AVFrame *ref[] = { ref0, ref1 };
295  int16_t *tmp[] = { lc->tmp + sb_bdof_flag * PROF_TEMP_OFFSET, lc->tmp1 + sb_bdof_flag * PROF_TEMP_OFFSET };
296  int denom, w0, w1, o0, o1;
297  const int weight_flag = derive_weight(&denom, &w0, &w1, &o0, &o1, lc, mvf, LUMA, pu->dmvr_flag);
298 
299  for (int i = L0; i <= L1; i++) {
300  const Mv *mv = mvf->mv + i;
301  const int mx = mv->x & 0xf;
302  const int my = mv->y & 0xf;
303  const int ox = x_off + (mv->x >> 4);
304  const int oy = y_off + (mv->y >> 4);
305  ptrdiff_t src_stride = ref[i]->linesize[0];
306  const uint8_t *src = ref[i]->data[0] + oy * src_stride + (ox * (1 << fc->ps.sps->pixel_shift));
307  const int8_t *hf = ff_vvc_inter_luma_filters[hf_idx][mx];
308  const int8_t *vf = ff_vvc_inter_luma_filters[vf_idx][my];
309 
310  if (pu->dmvr_flag) {
311  const int x_sb = x_off + (orig_mv->mv[i].x >> 4);
312  const int y_sb = y_off + (orig_mv->mv[i].y >> 4);
313 
314  EMULATED_EDGE_DMVR_LUMA(lc->edge_emu_buffer, &src, &src_stride, x_sb, y_sb, ox, oy);
315  } else {
316  EMULATED_EDGE_LUMA(lc->edge_emu_buffer, &src, &src_stride, ox, oy);
317  }
318  fc->vvcdsp.inter.put[LUMA][idx][!!my][!!mx](tmp[i], src, src_stride, block_h, hf, vf, block_w);
319  if (sb_bdof_flag)
320  fc->vvcdsp.inter.bdof_fetch_samples(tmp[i], src, src_stride, mx, my, block_w, block_h);
321  }
322 
323  if (sb_bdof_flag)
324  fc->vvcdsp.inter.apply_bdof(dst, dst_stride, tmp[L0], tmp[L1], block_w, block_h);
325  else if (weight_flag)
326  fc->vvcdsp.inter.w_avg(dst, dst_stride, tmp[L0], tmp[L1], block_w, block_h, denom, w0, w1, o0, o1);
327  else
328  fc->vvcdsp.inter.avg(dst, dst_stride, tmp[L0], tmp[L1], block_w, block_h);
329 }
330 
331 static void chroma_mc_uni(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
332  const uint8_t *src, ptrdiff_t src_stride, int x_off, int y_off,
333  const int block_w, const int block_h, const MvField *mvf, const int c_idx,
334  const int hf_idx, const int vf_idx)
335 {
336  const VVCFrameContext *fc = lc->fc;
337  const int lx = mvf->pred_flag - PF_L0;
338  const int hs = fc->ps.sps->hshift[1];
339  const int vs = fc->ps.sps->vshift[1];
340  const int idx = av_log2(block_w) - 1;
341  const Mv *mv = &mvf->mv[lx];
342  const intptr_t mx = av_mod_uintp2(mv->x, 4 + hs) << (1 - hs);
343  const intptr_t my = av_mod_uintp2(mv->y, 4 + vs) << (1 - vs);
344  const int8_t *hf = ff_vvc_inter_chroma_filters[hf_idx][mx];
345  const int8_t *vf = ff_vvc_inter_chroma_filters[vf_idx][my];
346  int denom, wx, ox;
347 
348  x_off += mv->x >> (4 + hs);
349  y_off += mv->y >> (4 + vs);
350  src += y_off * src_stride + (x_off * (1 << fc->ps.sps->pixel_shift));
351 
352 
353  EMULATED_EDGE_CHROMA(lc->edge_emu_buffer, &src, &src_stride, x_off, y_off);
354  if (derive_weight_uni(&denom, &wx, &ox, lc, mvf, c_idx)) {
355  fc->vvcdsp.inter.put_uni_w[CHROMA][idx][!!my][!!mx](dst, dst_stride, src, src_stride,
356  block_h, denom, wx, ox, hf, vf, block_w);
357  } else {
358  fc->vvcdsp.inter.put_uni[CHROMA][idx][!!my][!!mx](dst, dst_stride, src, src_stride,
359  block_h, hf, vf, block_w);
360  }
361 }
362 
363 static void chroma_mc_bi(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
364  const AVFrame *ref0, const AVFrame *ref1, const int x_off, const int y_off,
365  const int block_w, const int block_h, const MvField *mvf, const int c_idx,
366  const int hf_idx, const int vf_idx, const MvField *orig_mv, const int dmvr_flag, const int ciip_flag)
367 {
368  const VVCFrameContext *fc = lc->fc;
369  const int hs = fc->ps.sps->hshift[1];
370  const int vs = fc->ps.sps->vshift[1];
371  const int idx = av_log2(block_w) - 1;
372  const AVFrame *ref[] = { ref0, ref1 };
373  int16_t *tmp[] = { lc->tmp, lc->tmp1 };
374  int denom, w0, w1, o0, o1;
375  const int weight_flag = derive_weight(&denom, &w0, &w1, &o0, &o1, lc, mvf, c_idx, dmvr_flag);
376 
377  for (int i = L0; i <= L1; i++) {
378  const Mv *mv = mvf->mv + i;
379  const int mx = av_mod_uintp2(mv->x, 4 + hs) << (1 - hs);
380  const int my = av_mod_uintp2(mv->y, 4 + vs) << (1 - vs);
381  const int ox = x_off + (mv->x >> (4 + hs));
382  const int oy = y_off + (mv->y >> (4 + vs));
383  ptrdiff_t src_stride = ref[i]->linesize[c_idx];
384  const uint8_t *src = ref[i]->data[c_idx] + oy * src_stride + (ox * (1 << fc->ps.sps->pixel_shift));
385  const int8_t *hf = ff_vvc_inter_chroma_filters[hf_idx][mx];
386  const int8_t *vf = ff_vvc_inter_chroma_filters[vf_idx][my];
387  if (dmvr_flag) {
388  const int x_sb = x_off + (orig_mv->mv[i].x >> (4 + hs));
389  const int y_sb = y_off + (orig_mv->mv[i].y >> (4 + vs));
390  EMULATED_EDGE_DMVR_CHROMA(lc->edge_emu_buffer, &src, &src_stride, x_sb, y_sb, ox, oy);
391  } else {
392  EMULATED_EDGE_CHROMA(lc->edge_emu_buffer, &src, &src_stride, ox, oy);
393  }
394  fc->vvcdsp.inter.put[CHROMA][idx][!!my][!!mx](tmp[i], src, src_stride, block_h, hf, vf, block_w);
395  }
396  if (weight_flag)
397  fc->vvcdsp.inter.w_avg(dst, dst_stride, tmp[L0], tmp[L1], block_w, block_h, denom, w0, w1, o0, o1);
398  else
399  fc->vvcdsp.inter.avg(dst, dst_stride, tmp[L0], tmp[L1], block_w, block_h);
400 }
401 
402 static void luma_prof_uni(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
403  const AVFrame *ref, const MvField *mvf, int x_off, int y_off, const int block_w, const int block_h,
404  const int cb_prof_flag, const int16_t *diff_mv_x, const int16_t *diff_mv_y)
405 {
406  const VVCFrameContext *fc = lc->fc;
407  const uint8_t *src = ref->data[0];
408  ptrdiff_t src_stride = ref->linesize[0];
409  uint16_t *prof_tmp = lc->tmp + PROF_TEMP_OFFSET;
410  const int idx = av_log2(block_w) - 1;
411  const int lx = mvf->pred_flag - PF_L0;
412  const Mv *mv = mvf->mv + lx;
413  const int mx = mv->x & 0xf;
414  const int my = mv->y & 0xf;
415  const int8_t *hf = ff_vvc_inter_luma_filters[2][mx];
416  const int8_t *vf = ff_vvc_inter_luma_filters[2][my];
417  int denom, wx, ox;
418  const int weight_flag = derive_weight_uni(&denom, &wx, &ox, lc, mvf, LUMA);
419 
420  x_off += mv->x >> 4;
421  y_off += mv->y >> 4;
422  src += y_off * src_stride + (x_off * (1 << fc->ps.sps->pixel_shift));
423 
424  EMULATED_EDGE_LUMA(lc->edge_emu_buffer, &src, &src_stride, x_off, y_off);
425  if (cb_prof_flag) {
426  fc->vvcdsp.inter.put[LUMA][idx][!!my][!!mx](prof_tmp, src, src_stride, AFFINE_MIN_BLOCK_SIZE, hf, vf, AFFINE_MIN_BLOCK_SIZE);
427  fc->vvcdsp.inter.fetch_samples(prof_tmp, src, src_stride, mx, my);
428  if (!weight_flag)
429  fc->vvcdsp.inter.apply_prof_uni(dst, dst_stride, prof_tmp, diff_mv_x, diff_mv_y);
430  else
431  fc->vvcdsp.inter.apply_prof_uni_w(dst, dst_stride, prof_tmp, diff_mv_x, diff_mv_y, denom, wx, ox);
432  } else {
433  if (!weight_flag)
434  fc->vvcdsp.inter.put_uni[LUMA][idx][!!my][!!mx](dst, dst_stride, src, src_stride, block_h, hf, vf, block_w);
435  else
436  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);
437  }
438 }
439 
440 static void luma_prof_bi(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride,
441  const AVFrame *ref0, const AVFrame *ref1, const MvField *mvf, const int x_off, const int y_off,
442  const int block_w, const int block_h)
443 {
444  const VVCFrameContext *fc = lc->fc;
445  const PredictionUnit *pu = &lc->cu->pu;
446  const AVFrame *ref[] = { ref0, ref1 };
447  int16_t *tmp[] = { lc->tmp, lc->tmp1 };
448  uint16_t *prof_tmp = lc->tmp2 + PROF_TEMP_OFFSET;
449  const int idx = av_log2(block_w) - 1;
450  int denom, w0, w1, o0, o1;
451  const int weight_flag = derive_weight(&denom, &w0, &w1, &o0, &o1, lc, mvf, LUMA, 0);
452 
453  for (int i = L0; i <= L1; i++) {
454  const Mv *mv = mvf->mv + i;
455  const int mx = mv->x & 0xf;
456  const int my = mv->y & 0xf;
457  const int ox = x_off + (mv->x >> 4);
458  const int oy = y_off + (mv->y >> 4);
459  ptrdiff_t src_stride = ref[i]->linesize[0];
460  const uint8_t *src = ref[i]->data[0] + oy * src_stride + (ox * (1 << fc->ps.sps->pixel_shift));
461  const int8_t *hf = ff_vvc_inter_luma_filters[2][mx];
462  const int8_t *vf = ff_vvc_inter_luma_filters[2][my];
463 
464  EMULATED_EDGE_LUMA(lc->edge_emu_buffer, &src, &src_stride, ox, oy);
465  if (!pu->cb_prof_flag[i]) {
466  fc->vvcdsp.inter.put[LUMA][idx][!!my][!!mx](tmp[i], src, src_stride, block_h, hf, vf, block_w);
467  } else {
468  fc->vvcdsp.inter.put[LUMA][idx][!!my][!!mx](prof_tmp, src, src_stride, AFFINE_MIN_BLOCK_SIZE, hf, vf, AFFINE_MIN_BLOCK_SIZE);
469  fc->vvcdsp.inter.fetch_samples(prof_tmp, src, src_stride, mx, my);
470  fc->vvcdsp.inter.apply_prof(tmp[i], prof_tmp, pu->diff_mv_x[i], pu->diff_mv_y[i]);
471  }
472  }
473 
474  if (weight_flag)
475  fc->vvcdsp.inter.w_avg(dst, dst_stride, tmp[L0], tmp[L1], block_w, block_h, denom, w0, w1, o0, o1);
476  else
477  fc->vvcdsp.inter.avg(dst, dst_stride, tmp[L0], tmp[L1], block_w, block_h);
478 }
479 
480 static int pred_get_refs(const VVCLocalContext *lc, VVCFrame *ref[2], const MvField *mv)
481 {
482  const RefPicList *rpl = lc->sc->rpl;
483 
484  for (int mask = PF_L0; mask <= PF_L1; mask++) {
485  if (mv->pred_flag & mask) {
486  const int lx = mask - PF_L0;
487  ref[lx] = rpl[lx].ref[mv->ref_idx[lx]];
488  if (!ref[lx])
489  return AVERROR_INVALIDDATA;
490  }
491  }
492  return 0;
493 }
494 
495 #define POS(c_idx, x, y) \
496  &fc->frame->data[c_idx][((y) >> fc->ps.sps->vshift[c_idx]) * fc->frame->linesize[c_idx] + \
497  (((x) >> fc->ps.sps->hshift[c_idx]) << fc->ps.sps->pixel_shift)]
498 
500 {
501  const VVCFrameContext *fc = lc->fc;
502  const CodingUnit *cu = lc->cu;
503  const PredictionUnit *pu = &cu->pu;
504 
505  const uint8_t angle_idx = ff_vvc_gpm_angle_idx[pu->gpm_partition_idx];
506  const uint8_t weights_idx = ff_vvc_gpm_angle_to_weights_idx[angle_idx];
507  const int w = av_log2(cu->cb_width) - 3;
508  const int h = av_log2(cu->cb_height) - 3;
509  const uint8_t off_x = ff_vvc_gpm_weights_offset_x[pu->gpm_partition_idx][h][w];
510  const uint8_t off_y = ff_vvc_gpm_weights_offset_y[pu->gpm_partition_idx][h][w];
511  const uint8_t mirror_type = ff_vvc_gpm_angle_to_mirror[angle_idx];
512  const uint8_t *weights;
513 
514  const int c_end = fc->ps.sps->r->sps_chroma_format_idc ? 3 : 1;
515 
516  int16_t *tmp[2] = {lc->tmp, lc->tmp1};
517 
518  for (int c_idx = 0; c_idx < c_end; c_idx++) {
519  const int hs = fc->ps.sps->hshift[c_idx];
520  const int vs = fc->ps.sps->vshift[c_idx];
521  const int x = lc->cu->x0 >> hs;
522  const int y = lc->cu->y0 >> vs;
523  const int width = cu->cb_width >> hs;
524  const int height = cu->cb_height >> vs;
525  uint8_t *dst = POS(c_idx, lc->cu->x0, lc->cu->y0);
526  ptrdiff_t dst_stride = fc->frame->linesize[c_idx];
527 
528  int step_x = 1 << hs;
529  int step_y = VVC_GPM_WEIGHT_SIZE << vs;
530  if (!mirror_type) {
531  weights = &ff_vvc_gpm_weights[weights_idx][off_y * VVC_GPM_WEIGHT_SIZE + off_x];
532  } else if (mirror_type == 1) {
533  step_x = -step_x;
534  weights = &ff_vvc_gpm_weights[weights_idx][off_y * VVC_GPM_WEIGHT_SIZE + VVC_GPM_WEIGHT_SIZE - 1- off_x];
535  } else {
536  step_y = -step_y;
537  weights = &ff_vvc_gpm_weights[weights_idx][(VVC_GPM_WEIGHT_SIZE - 1 - off_y) * VVC_GPM_WEIGHT_SIZE + off_x];
538  }
539 
540  for (int i = 0; i < 2; i++) {
541  const MvField *mv = pu->gpm_mv + i;
542  const int lx = mv->pred_flag - PF_L0;
543  VVCFrame *ref = lc->sc->rpl[lx].ref[mv->ref_idx[lx]];
544  if (!ref)
545  return;
546  if (c_idx)
547  chroma_mc(lc, tmp[i], ref->frame, mv->mv + lx, x, y, width, height, c_idx);
548  else
549  luma_mc(lc, tmp[i], ref->frame, mv->mv + lx, x, y, width, height);
550  }
551  fc->vvcdsp.inter.put_gpm(dst, dst_stride, width, height, tmp[0], tmp[1], weights, step_x, step_y);
552  }
553  return;
554 }
555 
556 static int ciip_derive_intra_weight(const VVCLocalContext *lc, const int x0, const int y0,
557  const int width, const int height)
558 {
559  const VVCFrameContext *fc = lc->fc;
560  const VVCSPS *sps = fc->ps.sps;
561  const int x0b = av_mod_uintp2(x0, sps->ctb_log2_size_y);
562  const int y0b = av_mod_uintp2(y0, sps->ctb_log2_size_y);
563  const int available_l = lc->ctb_left_flag || x0b;
564  const int available_u = lc->ctb_up_flag || y0b;
565  const int min_pu_width = fc->ps.pps->min_pu_width;
566 
567  int w = 1;
568 
569  if (available_u &&fc->tab.mvf[((y0 - 1) >> MIN_PU_LOG2) * min_pu_width + ((x0 - 1 + width)>> MIN_PU_LOG2)].pred_flag == PF_INTRA)
570  w++;
571 
572  if (available_l && fc->tab.mvf[((y0 - 1 + height)>> MIN_PU_LOG2) * min_pu_width + ((x0 - 1) >> MIN_PU_LOG2)].pred_flag == PF_INTRA)
573  w++;
574 
575  return w;
576 }
577 
578 static void pred_regular_luma(VVCLocalContext *lc, const int hf_idx, const int vf_idx, const MvField *mv,
579  const int x0, const int y0, const int sbw, const int sbh, const MvField *orig_mv, const int sb_bdof_flag)
580 {
581  const SliceContext *sc = lc->sc;
582  const VVCFrameContext *fc = lc->fc;
583  const int ciip_flag = lc->cu->ciip_flag;
584  uint8_t *dst = POS(0, x0, y0);
585  const ptrdiff_t dst_stride = fc->frame->linesize[0];
586  uint8_t *inter = ciip_flag ? (uint8_t *)lc->ciip_tmp1 : dst;
587  const ptrdiff_t inter_stride = ciip_flag ? (MAX_PB_SIZE * sizeof(uint16_t)) : dst_stride;
588  VVCFrame *ref[2];
589 
590  if (pred_get_refs(lc, ref, mv) < 0)
591  return;
592 
593  if (mv->pred_flag != PF_BI) {
594  const int lx = mv->pred_flag - PF_L0;
595  luma_mc_uni(lc, inter, inter_stride, ref[lx]->frame,
596  mv, x0, y0, sbw, sbh, hf_idx, vf_idx);
597  } else {
598  luma_mc_bi(lc, inter, inter_stride, ref[0]->frame,
599  &mv->mv[0], x0, y0, sbw, sbh, ref[1]->frame, &mv->mv[1], mv,
600  hf_idx, vf_idx, orig_mv, sb_bdof_flag);
601  }
602 
603  if (ciip_flag) {
604  const int intra_weight = ciip_derive_intra_weight(lc, x0, y0, sbw, sbh);
605  fc->vvcdsp.intra.intra_pred(lc, x0, y0, sbw, sbh, 0);
606  if (sc->sh.r->sh_lmcs_used_flag)
607  fc->vvcdsp.lmcs.filter(inter, inter_stride, sbw, sbh, &fc->ps.lmcs.fwd_lut);
608  fc->vvcdsp.inter.put_ciip(dst, dst_stride, sbw, sbh, inter, inter_stride, intra_weight);
609 
610  }
611 }
612 
614  const int x0, const int y0, const int sbw, const int sbh, const MvField *orig_mv, const int dmvr_flag)
615 {
616  const VVCFrameContext *fc = lc->fc;
617  const int hs = fc->ps.sps->hshift[1];
618  const int vs = fc->ps.sps->vshift[1];
619  const int x0_c = x0 >> hs;
620  const int y0_c = y0 >> vs;
621  const int w_c = sbw >> hs;
622  const int h_c = sbh >> vs;
623  const int do_ciip = lc->cu->ciip_flag && (w_c > 2);
624 
625  uint8_t* dst1 = POS(1, x0, y0);
626  uint8_t* dst2 = POS(2, x0, y0);
627  const ptrdiff_t dst1_stride = fc->frame->linesize[1];
628  const ptrdiff_t dst2_stride = fc->frame->linesize[2];
629 
630  uint8_t *inter1 = do_ciip ? (uint8_t *)lc->ciip_tmp1 : dst1;
631  const ptrdiff_t inter1_stride = do_ciip ? (MAX_PB_SIZE * sizeof(uint16_t)) : dst1_stride;
632 
633  uint8_t *inter2 = do_ciip ? (uint8_t *)lc->ciip_tmp2 : dst2;
634  const ptrdiff_t inter2_stride = do_ciip ? (MAX_PB_SIZE * sizeof(uint16_t)) : dst2_stride;
635 
636  //fix me
637  const int hf_idx = 0;
638  const int vf_idx = 0;
639  VVCFrame *ref[2];
640 
641  if (pred_get_refs(lc, ref, mv) < 0)
642  return;
643 
644  if (mv->pred_flag != PF_BI) {
645  const int lx = mv->pred_flag - PF_L0;
646  if (!ref[lx])
647  return;
648 
649  chroma_mc_uni(lc, inter1, inter1_stride, ref[lx]->frame->data[1], ref[lx]->frame->linesize[1],
650  x0_c, y0_c, w_c, h_c, mv, CB, hf_idx, vf_idx);
651  chroma_mc_uni(lc, inter2, inter2_stride, ref[lx]->frame->data[2], ref[lx]->frame->linesize[2],
652  x0_c, y0_c, w_c, h_c, mv, CR, hf_idx, vf_idx);
653  } else {
654  if (!ref[0] || !ref[1])
655  return;
656 
657  chroma_mc_bi(lc, inter1, inter1_stride, ref[0]->frame, ref[1]->frame,
658  x0_c, y0_c, w_c, h_c, mv, CB, hf_idx, vf_idx, orig_mv, dmvr_flag, lc->cu->ciip_flag);
659 
660  chroma_mc_bi(lc, inter2, inter2_stride, ref[0]->frame, ref[1]->frame,
661  x0_c, y0_c, w_c, h_c, mv, CR, hf_idx, vf_idx, orig_mv, dmvr_flag, lc->cu->ciip_flag);
662 
663  }
664  if (do_ciip) {
665  const int intra_weight = ciip_derive_intra_weight(lc, x0, y0, sbw, sbh);
666  fc->vvcdsp.intra.intra_pred(lc, x0, y0, sbw, sbh, 1);
667  fc->vvcdsp.intra.intra_pred(lc, x0, y0, sbw, sbh, 2);
668  fc->vvcdsp.inter.put_ciip(dst1, dst1_stride, w_c, h_c, inter1, inter1_stride, intra_weight);
669  fc->vvcdsp.inter.put_ciip(dst2, dst2_stride, w_c, h_c, inter2, inter2_stride, intra_weight);
670 
671  }
672 }
673 
674 // 8.5.3.5 Parametric motion vector refinement process
675 static int parametric_mv_refine(const int *sad, const int stride)
676 {
677  const int sad_minus = sad[-stride];
678  const int sad_center = sad[0];
679  const int sad_plus = sad[stride];
680  int dmvc;
681  int denom = (( sad_minus + sad_plus) - (sad_center << 1 ) ) << 3;
682  if (!denom)
683  dmvc = 0;
684  else {
685  if (sad_minus == sad_center)
686  dmvc = -8;
687  else if (sad_plus == sad_center)
688  dmvc = 8;
689  else {
690  int num = ( sad_minus - sad_plus ) * (1 << 4);
691  int sign_num = 0;
692  int quotient = 0;
693  int counter = 3;
694  if (num < 0 ) {
695  num = - num;
696  sign_num = 1;
697  }
698  while (counter > 0) {
699  counter = counter - 1;
700  quotient = quotient << 1;
701  if ( num >= denom ) {
702  num = num - denom;
703  quotient = quotient + 1;
704  }
705  denom = (denom >> 1);
706  }
707  if (sign_num == 1 )
708  dmvc = -quotient;
709  else
710  dmvc = quotient;
711  }
712  }
713  return dmvc;
714 }
715 
716 #define SAD_ARRAY_SIZE 5
717 //8.5.3 Decoder-side motion vector refinement process
718 static void dmvr_mv_refine(VVCLocalContext *lc, MvField *mvf, MvField *orig_mv, int *sb_bdof_flag,
719  const AVFrame *ref0, const AVFrame *ref1, const int x_off, const int y_off, const int block_w, const int block_h)
720 {
721  const VVCFrameContext *fc = lc->fc;
722  const int sr_range = 2;
723  const AVFrame *ref[] = { ref0, ref1 };
724  int16_t *tmp[] = { lc->tmp, lc->tmp1 };
725  int sad[SAD_ARRAY_SIZE][SAD_ARRAY_SIZE];
726  int min_dx, min_dy, min_sad, dx, dy;
727 
728  *orig_mv = *mvf;
729  min_dx = min_dy = dx = dy = 2;
730 
731  for (int i = L0; i <= L1; i++) {
732  const int pred_w = block_w + 2 * sr_range;
733  const int pred_h = block_h + 2 * sr_range;
734  const Mv *mv = mvf->mv + i;
735  const int mx = mv->x & 0xf;
736  const int my = mv->y & 0xf;
737  const int ox = x_off + (mv->x >> 4) - sr_range;
738  const int oy = y_off + (mv->y >> 4) - sr_range;
739  ptrdiff_t src_stride = ref[i]->linesize[LUMA];
740  const uint8_t *src = ref[i]->data[LUMA] + oy * src_stride + (ox * (1 << fc->ps.sps->pixel_shift));
741  EMULATED_EDGE_BILINEAR(lc->edge_emu_buffer, &src, &src_stride, ox, oy);
742  fc->vvcdsp.inter.dmvr[!!my][!!mx](tmp[i], src, src_stride, pred_h, mx, my, pred_w);
743  }
744 
745  min_sad = fc->vvcdsp.inter.sad(tmp[L0], tmp[L1], dx, dy, block_w, block_h);
746  min_sad -= min_sad >> 2;
747  sad[dy][dx] = min_sad;
748 
749  if (min_sad >= block_w * block_h) {
750  int dmv[2];
751  // 8.5.3.4 Array entry selection process
752  for (dy = 0; dy < SAD_ARRAY_SIZE; dy++) {
753  for (dx = 0; dx < SAD_ARRAY_SIZE; dx++) {
754  if (dx != sr_range || dy != sr_range) {
755  sad[dy][dx] = fc->vvcdsp.inter.sad(lc->tmp, lc->tmp1, dx, dy, block_w, block_h);
756  if (sad[dy][dx] < min_sad) {
757  min_sad = sad[dy][dx];
758  min_dx = dx;
759  min_dy = dy;
760  }
761  }
762  }
763  }
764  dmv[0] = (min_dx - sr_range) * (1 << 4);
765  dmv[1] = (min_dy - sr_range) * (1 << 4);
766  if (min_dx != 0 && min_dx != 4 && min_dy != 0 && min_dy != 4) {
767  dmv[0] += parametric_mv_refine(&sad[min_dy][min_dx], 1);
768  dmv[1] += parametric_mv_refine(&sad[min_dy][min_dx], SAD_ARRAY_SIZE);
769  }
770 
771  for (int i = L0; i <= L1; i++) {
772  Mv *mv = mvf->mv + i;
773  mv->x += (1 - 2 * i) * dmv[0];
774  mv->y += (1 - 2 * i) * dmv[1];
776  }
777  }
778  if (min_sad < 2 * block_w * block_h) {
779  *sb_bdof_flag = 0;
780  }
781 }
782 
783 static void set_dmvr_info(VVCFrameContext *fc, const int x0, const int y0,
784  const int width, const int height, const MvField *mvf)
785 
786 {
787  const VVCPPS *pps = fc->ps.pps;
788 
789  for (int y = y0; y < y0 + height; y += MIN_PU_SIZE) {
790  for (int x = x0; x < x0 + width; x += MIN_PU_SIZE) {
791  const int idx = pps->min_pu_width * (y >> MIN_PU_LOG2) + (x >> MIN_PU_LOG2);
792  fc->ref->tab_dmvr_mvf[idx] = *mvf;
793  }
794  }
795 }
796 
797 static void derive_sb_mv(VVCLocalContext *lc, MvField *mv, MvField *orig_mv, int *sb_bdof_flag,
798  const int x0, const int y0, const int sbw, const int sbh)
799 {
800  VVCFrameContext *fc = lc->fc;
801  const PredictionUnit *pu = &lc->cu->pu;
802 
803  *orig_mv = *mv = *ff_vvc_get_mvf(fc, x0, y0);
804  if (pu->bdof_flag)
805  *sb_bdof_flag = 1;
806  if (pu->dmvr_flag) {
807  VVCFrame* ref[2];
808  if (pred_get_refs(lc, ref, mv) < 0)
809  return;
810  dmvr_mv_refine(lc, mv, orig_mv, sb_bdof_flag, ref[0]->frame, ref[1]->frame, x0, y0, sbw, sbh);
811  set_dmvr_info(fc, x0, y0, sbw, sbh, mv);
812  }
813 }
814 
815 static void pred_regular_blk(VVCLocalContext *lc, const int skip_ciip)
816 {
817  const VVCFrameContext *fc = lc->fc;
818  const CodingUnit *cu = lc->cu;
819  PredictionUnit *pu = &lc->cu->pu;
820  const MotionInfo *mi = &pu->mi;
821  MvField mv, orig_mv;
822  int sbw, sbh, sb_bdof_flag = 0;
823 
824  if (cu->ciip_flag && skip_ciip)
825  return;
826 
827  sbw = cu->cb_width / mi->num_sb_x;
828  sbh = cu->cb_height / mi->num_sb_y;
829 
830  for (int sby = 0; sby < mi->num_sb_y; sby++) {
831  for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
832  const int x0 = cu->x0 + sbx * sbw;
833  const int y0 = cu->y0 + sby * sbh;
834 
835  if (cu->ciip_flag)
836  ff_vvc_set_neighbour_available(lc, x0, y0, sbw, sbh);
837 
838  derive_sb_mv(lc, &mv, &orig_mv, &sb_bdof_flag, x0, y0, sbw, sbh);
839  pred_regular_luma(lc, mi->hpel_if_idx, mi->hpel_if_idx, &mv, x0, y0, sbw, sbh, &orig_mv, sb_bdof_flag);
840  if (fc->ps.sps->r->sps_chroma_format_idc)
841  pred_regular_chroma(lc, &mv, x0, y0, sbw, sbh, &orig_mv, pu->dmvr_flag);
842  }
843  }
844 }
845 
846 static void derive_affine_mvc(MvField *mvc, const VVCFrameContext *fc, const MvField *mv,
847  const int x0, const int y0, const int sbw, const int sbh)
848 {
849  const int hs = fc->ps.sps->hshift[1];
850  const int vs = fc->ps.sps->vshift[1];
851  const MvField* mv2 = ff_vvc_get_mvf(fc, x0 + hs * sbw, y0 + vs * sbh);
852  *mvc = *mv;
853 
854  // Due to different pred_flag, one of the motion vectors may have an invalid value.
855  // Cast them to an unsigned type to avoid undefined behavior.
856  mvc->mv[0].x += (unsigned int)mv2->mv[0].x;
857  mvc->mv[0].y += (unsigned int)mv2->mv[0].y;
858  mvc->mv[1].x += (unsigned int)mv2->mv[1].x;
859  mvc->mv[1].y += (unsigned int)mv2->mv[1].y;
860  ff_vvc_round_mv(mvc->mv + 0, 0, 1);
861  ff_vvc_round_mv(mvc->mv + 1, 0, 1);
862 }
863 
865 {
866  const VVCFrameContext *fc = lc->fc;
867  const CodingUnit *cu = lc->cu;
868  const PredictionUnit *pu = &cu->pu;
869  const MotionInfo *mi = &pu->mi;
870  const int x0 = cu->x0;
871  const int y0 = cu->y0;
872  const int sbw = cu->cb_width / mi->num_sb_x;
873  const int sbh = cu->cb_height / mi->num_sb_y;
874  const int hs = fc->ps.sps->hshift[1];
875  const int vs = fc->ps.sps->vshift[1];
876 
877  for (int sby = 0; sby < mi->num_sb_y; sby++) {
878  for (int sbx = 0; sbx < mi->num_sb_x; sbx++) {
879  const int x = x0 + sbx * sbw;
880  const int y = y0 + sby * sbh;
881 
882  uint8_t *dst0 = POS(0, x, y);
883  const MvField *mv = ff_vvc_get_mvf(fc, x, y);
884  VVCFrame *ref[2];
885 
886  if (pred_get_refs(lc, ref, mv) < 0)
887  return;
888 
889  if (mi->pred_flag != PF_BI) {
890  const int lx = mi->pred_flag - PF_L0;
891  luma_prof_uni(lc, dst0, fc->frame->linesize[0], ref[lx]->frame,
892  mv, x, y, sbw, sbh, pu->cb_prof_flag[lx],
893  pu->diff_mv_x[lx], pu->diff_mv_y[lx]);
894  } else {
895  luma_prof_bi(lc, dst0, fc->frame->linesize[0], ref[0]->frame, ref[1]->frame,
896  mv, x, y, sbw, sbh);
897  }
898  if (fc->ps.sps->r->sps_chroma_format_idc) {
899  if (!av_mod_uintp2(sby, vs) && !av_mod_uintp2(sbx, hs)) {
900  MvField mvc;
901  derive_affine_mvc(&mvc, fc, mv, x, y, sbw, sbh);
902  pred_regular_chroma(lc, &mvc, x, y, sbw<<hs, sbh<<vs, NULL, 0);
903 
904  }
905  }
906 
907  }
908  }
909 }
910 
912 {
913  const VVCFrameContext *fc = lc->fc;
914  const CodingUnit *cu = lc->cu;
915  const PredictionUnit *pu = &cu->pu;
916 
917  if (pu->merge_gpm_flag)
918  pred_gpm_blk(lc);
919  else if (pu->inter_affine_flag)
920  pred_affine_blk(lc);
921  else
922  pred_regular_blk(lc, 1); //intra block is not ready yet, skip ciip
923 
924  if (lc->sc->sh.r->sh_lmcs_used_flag && !cu->ciip_flag) {
925  uint8_t* dst0 = POS(0, cu->x0, cu->y0);
926  fc->vvcdsp.lmcs.filter(dst0, fc->frame->linesize[LUMA], cu->cb_width, cu->cb_height, &fc->ps.lmcs.fwd_lut);
927  }
928 }
929 
930 static int has_inter_luma(const CodingUnit *cu)
931 {
932  return (cu->pred_mode == MODE_INTER || cu->pred_mode == MODE_SKIP) && cu->tree_type != DUAL_TREE_CHROMA;
933 }
934 
935 int ff_vvc_predict_inter(VVCLocalContext *lc, const int rs)
936 {
937  const VVCFrameContext *fc = lc->fc;
938  const CTU *ctu = fc->tab.ctus + rs;
939  CodingUnit *cu = ctu->cus;
940 
941  while (cu) {
942  lc->cu = cu;
943  if (has_inter_luma(cu))
944  predict_inter(lc);
945  cu = cu->next;
946  }
947 
948  return 0;
949 }
950 
952 {
953  av_assert0(lc->cu->ciip_flag);
954 
955  //todo: refact out ciip from pred_regular_blk
956  pred_regular_blk(lc, 0);
957 }
958 
959 #undef POS
ff_vvc_gpm_weights
const uint8_t ff_vvc_gpm_weights[6][VVC_GPM_WEIGHT_SIZE *VVC_GPM_WEIGHT_SIZE]
Definition: vvc_data.c:2801
CHROMA_EXTRA_AFTER
#define CHROMA_EXTRA_AFTER
Definition: vvc_ctu.h:52
CB
#define CB
Definition: hevc_filter.c:32
EMULATED_EDGE_DMVR_LUMA
#define EMULATED_EDGE_DMVR_LUMA(dst, src, src_stride, x_sb, y_sb, x_off, y_off)
Definition: vvc_inter.c:152
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
VVCPPS
Definition: vvc_ps.h:92
has_inter_luma
static int has_inter_luma(const CodingUnit *cu)
Definition: vvc_inter.c:930
MotionInfo
Definition: vvc_ctu.h:236
PROF_TEMP_OFFSET
#define PROF_TEMP_OFFSET
Definition: vvc_inter.c:30
pred_regular_luma
static void pred_regular_luma(VVCLocalContext *lc, const int hf_idx, const int vf_idx, const MvField *mv, const int x0, const int y0, const int sbw, const int sbh, const MvField *orig_mv, const int sb_bdof_flag)
Definition: vvc_inter.c:578
ff_vvc_get_mvf
MvField * ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0)
Definition: vvc_mvs.c:1922
CodingUnit
Definition: hevcdec.h:282
mv
static const int8_t mv[256][2]
Definition: 4xm.c:81
ff_vvc_predict_inter
int ff_vvc_predict_inter(VVCLocalContext *lc, const int rs)
Loop entire CTU to predict all inter coding blocks.
Definition: vvc_inter.c:935
PredictionUnit::gpm_partition_idx
uint8_t gpm_partition_idx
Definition: vvc_ctu.h:258
VVCLocalContext::tmp
int16_t tmp[MAX_PB_SIZE *MAX_PB_SIZE]
Definition: vvc_ctu.h:380
MIN_PU_LOG2
#define MIN_PU_LOG2
Definition: vvcdec.h:40
av_mod_uintp2
#define av_mod_uintp2
Definition: common.h:126
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:375
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
w
uint8_t w
Definition: llviddspenc.c:38
VVCLocalContext::sc
SliceContext * sc
Definition: vvc_ctu.h:432
ff_vvc_gpm_angle_idx
const uint8_t ff_vvc_gpm_angle_idx[VVC_GPM_NUM_PARTITION]
Definition: vvc_data.c:1998
CHROMA_EXTRA_BEFORE
#define CHROMA_EXTRA_BEFORE
Definition: h2656_inter_template.c:24
Mv::y
int16_t y
vertical component of motion vector
Definition: hevcdec.h:297
VVCSH::r
const H266RawSliceHeader * r
RefStruct reference.
Definition: vvc_ps.h:229
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:464
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
EMULATED_EDGE_BILINEAR
#define EMULATED_EDGE_BILINEAR(dst, src, src_stride, x_off, y_off)
Definition: vvc_inter.c:158
RefPicList
Definition: hevcdec.h:189
ff_vvc_gpm_angle_to_weights_idx
const uint8_t ff_vvc_gpm_angle_to_weights_idx[VVC_GPM_NUM_ANGLES]
Definition: vvc_data.c:2021
PF_INTRA
@ PF_INTRA
Definition: hevcdec.h:113
luma_prof_uni
static void luma_prof_uni(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const AVFrame *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: vvc_inter.c:402
MODE_SKIP
@ MODE_SKIP
Definition: hevcdec.h:103
EMULATED_EDGE_CHROMA
#define EMULATED_EDGE_CHROMA(dst, src, src_stride, x_off, y_off)
Definition: vvc_inter.c:149
PredictionUnit::gpm_mv
MvField gpm_mv[2]
Definition: vvc_ctu.h:259
vvc_data.h
VVCLocalContext::fc
VVCFrameContext * fc
Definition: vvc_ctu.h:433
VVCSH::pwt
PredWeightTable pwt
Definition: vvc_ps.h:237
PredictionUnit
Definition: hevcdec.h:315
MODE_INTER
@ MODE_INTER
Definition: hevcdec.h:101
VVCLocalContext::tmp1
int16_t tmp1[MAX_PB_SIZE *MAX_PB_SIZE]
Definition: vvc_ctu.h:381
vvc_refs.h
SliceContext::rpl
RefPicList * rpl
Definition: vvcdec.h:88
luma_mc
static void luma_mc(VVCLocalContext *lc, int16_t *dst, const AVFrame *ref, const Mv *mv, int x_off, int y_off, const int block_w, const int block_h)
Definition: vvc_inter.c:212
CodingUnit::cb_width
int cb_width
Definition: vvc_ctu.h:278
ff_vvc_inter_chroma_filters
const int8_t ff_vvc_inter_chroma_filters[VVC_INTER_FILTER_TYPES][VVC_INTER_CHROMA_FACTS][VVC_INTER_CHROMA_TAPS]
Definition: vvc_data.c:1798
CodingUnit::pu
PredictionUnit pu
Definition: vvc_ctu.h:323
chroma_mc_bi
static void chroma_mc_bi(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const AVFrame *ref0, const AVFrame *ref1, const int x_off, const int y_off, const int block_w, const int block_h, const MvField *mvf, const int c_idx, const int hf_idx, const int vf_idx, const MvField *orig_mv, const int dmvr_flag, const int ciip_flag)
Definition: vvc_inter.c:363
EMULATED_EDGE_DMVR_CHROMA
#define EMULATED_EDGE_DMVR_CHROMA(dst, src, src_stride, x_sb, y_sb, x_off, y_off)
Definition: vvc_inter.c:155
mask
static const uint16_t mask[17]
Definition: lzw.c:38
width
#define width
luma_prof_bi
static void luma_prof_bi(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const AVFrame *ref0, const AVFrame *ref1, const MvField *mvf, const int x_off, const int y_off, const int block_w, const int block_h)
Definition: vvc_inter.c:440
mi
#define mi
Definition: vf_colormatrix.c:106
vvc_mvs.h
EMULATED_EDGE_LUMA
#define EMULATED_EDGE_LUMA(dst, src, src_stride, x_off, y_off)
Definition: vvc_inter.c:146
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
luma_mc_bi
static void luma_mc_bi(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const AVFrame *ref0, const Mv *mv0, const int x_off, const int y_off, const int block_w, const int block_h, const AVFrame *ref1, const Mv *mv1, const MvField *mvf, const int hf_idx, const int vf_idx, const MvField *orig_mv, const int sb_bdof_flag)
Definition: vvc_inter.c:286
VVCSH
Definition: vvc_ps.h:228
PredWeightTable
Definition: vvc_ps.h:137
RefPicList::ref
struct HEVCFrame * ref[HEVC_MAX_REFS]
Definition: hevcdec.h:190
CodingUnit::tree_type
VVCTreeType tree_type
Definition: vvc_ctu.h:275
LUMA_EXTRA
#define LUMA_EXTRA
Definition: h2656_inter_template.c:27
bcw_w_lut
static const int bcw_w_lut[]
Definition: vvc_inter.c:31
PredictionUnit::bdof_flag
uint8_t bdof_flag
Definition: vvc_ctu.h:267
derive_weight
static int derive_weight(int *denom, int *w0, int *w1, int *o0, int *o1, const VVCLocalContext *lc, const MvField *mvf, const int c_idx, const int dmvr_flag)
Definition: vvc_inter.c:182
pred_regular_chroma
static void pred_regular_chroma(VVCLocalContext *lc, const MvField *mv, const int x0, const int y0, const int sbw, const int sbh, const MvField *orig_mv, const int dmvr_flag)
Definition: vvc_inter.c:613
H266RawSliceHeader::sh_lmcs_used_flag
uint8_t sh_lmcs_used_flag
Definition: cbs_h266.h:792
LUMA_EXTRA_AFTER
#define LUMA_EXTRA_AFTER
Definition: vvc_ctu.h:55
CTU
Definition: vvc_ctu.h:328
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: vvc_inter.c:556
NULL
#define NULL
Definition: coverity.c:32
subpic_width_height
static void subpic_width_height(int *pic_width, int *pic_height, const VVCSPS *sps, const VVCPPS *pps, const int subpic_idx, const int is_luma)
Definition: vvc_inter.c:40
VVCLocalContext
Definition: vvc_ctu.h:368
H266RawSliceHeader::curr_subpic_idx
uint16_t curr_subpic_idx
CurrSubpicIdx.
Definition: cbs_h266.h:835
luma_mc_uni
static void luma_mc_uni(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const AVFrame *ref, const MvField *mvf, int x_off, int y_off, const int block_w, const int block_h, const int hf_idx, const int vf_idx)
Definition: vvc_inter.c:255
L0
#define L0
Definition: hevcdec.h:57
SAD_ARRAY_SIZE
#define SAD_ARRAY_SIZE
Definition: vvc_inter.c:716
LUMA_EXTRA_BEFORE
#define LUMA_EXTRA_BEFORE
Definition: h2656_inter_template.c:26
parametric_mv_refine
static int parametric_mv_refine(const int *sad, const int stride)
Definition: vvc_inter.c:675
Mv::x
int16_t x
horizontal component of motion vector
Definition: hevcdec.h:296
PF_BI
@ PF_BI
Definition: hevcdec.h:116
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: vvc_inter.c:162
SliceContext
Definition: mss12.h:70
chroma_mc
static void chroma_mc(VVCLocalContext *lc, int16_t *dst, const AVFrame *ref, const Mv *mv, int x_off, int y_off, const int block_w, const int block_h, const int c_idx)
Definition: vvc_inter.c:233
DUAL_TREE_CHROMA
@ DUAL_TREE_CHROMA
Definition: vvc_ctu.h:164
pps
static int FUNC() pps(CodedBitstreamContext *ctx, RWContext *rw, H264RawPPS *current)
Definition: cbs_h264_syntax_template.c:404
pred_gpm_blk
static void pred_gpm_blk(VVCLocalContext *lc)
Definition: vvc_inter.c:499
AFFINE_MIN_BLOCK_SIZE
#define AFFINE_MIN_BLOCK_SIZE
Definition: vvc_ctu.h:63
PredictionUnit::merge_gpm_flag
uint8_t merge_gpm_flag
Definition: vvc_ctu.h:257
PredictionUnit::cb_prof_flag
int cb_prof_flag[2]
Definition: vvc_ctu.h:271
CR
#define CR
Definition: hevc_filter.c:33
MvField
Definition: hevcdec.h:300
frame.h
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: vvc_inter.c:797
PF_L1
@ PF_L1
Definition: hevcdec.h:115
VVCLocalContext::ctb_up_flag
uint8_t ctb_up_flag
Definition: vvc_ctu.h:370
PredictionUnit::diff_mv_x
int16_t diff_mv_x[2][AFFINE_MIN_BLOCK_SIZE *AFFINE_MIN_BLOCK_SIZE]
diffMvLX
Definition: vvc_ctu.h:269
VVCFrame
Definition: vvcdec.h:56
VVCLocalContext::edge_emu_buffer
uint8_t edge_emu_buffer[(MAX_PB_SIZE+7) *EDGE_EMU_BUFFER_STRIDE *2]
Definition: vvc_ctu.h:377
height
#define height
pred_affine_blk
static void pred_affine_blk(VVCLocalContext *lc)
Definition: vvc_inter.c:864
VVC_GPM_WEIGHT_SIZE
#define VVC_GPM_WEIGHT_SIZE
Definition: vvc_data.h:64
ff_vvc_gpm_weights_offset_x
const uint8_t ff_vvc_gpm_weights_offset_x[VVC_GPM_NUM_PARTITION][4][4]
Definition: vvc_data.c:2027
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
MIN_PU_SIZE
#define MIN_PU_SIZE
Definition: vvc_ctu.h:40
MvField::pred_flag
int8_t pred_flag
Definition: hevcdec.h:303
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: vvc_intra_template.c:877
PredictionUnit::mi
MotionInfo mi
Definition: vvc_ctu.h:263
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
MAX_PB_SIZE
#define MAX_PB_SIZE
Definition: hevcdsp.h:32
weights
static const int weights[]
Definition: hevc_pel.c:32
VVCLocalContext::ciip_tmp2
uint8_t ciip_tmp2[MAX_PB_SIZE *MAX_PB_SIZE *2]
Definition: vvc_ctu.h:384
IS_B
#define IS_B(rsh)
Definition: vvc_ps.h:40
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
PF_L0
@ PF_L0
Definition: hevcdec.h:114
EDGE_EMU_BUFFER_STRIDE
#define EDGE_EMU_BUFFER_STRIDE
Definition: hevcdec.h:67
chroma_mc_uni
static void chroma_mc_uni(VVCLocalContext *lc, uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, int x_off, int y_off, const int block_w, const int block_h, const MvField *mvf, const int c_idx, const int hf_idx, const int vf_idx)
Definition: vvc_inter.c:331
CodingUnit::x0
int x0
Definition: vvc_ctu.h:276
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: vvc_ctu.c:2507
dmvr_mv_refine
static void dmvr_mv_refine(VVCLocalContext *lc, MvField *mvf, MvField *orig_mv, int *sb_bdof_flag, const AVFrame *ref0, const AVFrame *ref1, const int x_off, const int y_off, const int block_w, const int block_h)
Definition: vvc_inter.c:718
VVCLocalContext::cu
CodingUnit * cu
Definition: vvc_ctu.h:416
stride
#define stride
Definition: h264pred_template.c:537
ff_vvc_clip_mv
void ff_vvc_clip_mv(Mv *mv)
Definition: vvc_mvs.c:1862
CHROMA_EXTRA
#define CHROMA_EXTRA
Definition: h2656_inter_template.c:25
PredictionUnit::dmvr_flag
uint8_t dmvr_flag
Definition: vvc_ctu.h:266
emulated_edge_dmvr
static void emulated_edge_dmvr(const VVCLocalContext *lc, uint8_t *dst, const uint8_t **src, ptrdiff_t *src_stride, int x_sb, int y_sb, int x_off, int y_off, const int block_w, const int block_h, const int is_luma)
Definition: vvc_inter.c:80
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
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: vvc_inter.c:846
ff_vvc_predict_ciip
void ff_vvc_predict_ciip(VVCLocalContext *lc)
CIIP(Combined Inter-Intra Prediction) for a coding block.
Definition: vvc_inter.c:951
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
PredictionUnit::inter_affine_flag
uint8_t inter_affine_flag
Definition: vvc_ctu.h:252
emulated_edge_bilinear
static void emulated_edge_bilinear(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)
Definition: vvc_inter.c:118
CodingUnit::cb_height
int cb_height
Definition: vvc_ctu.h:279
ff_vvc_gpm_angle_to_mirror
const uint8_t ff_vvc_gpm_angle_to_mirror[VVC_GPM_NUM_ANGLES]
Definition: vvc_data.c:2016
BILINEAR_EXTRA_AFTER
#define BILINEAR_EXTRA_AFTER
Definition: vvc_ctu.h:58
IS_P
#define IS_P(rsh)
Definition: vvc_ps.h:39
predict_inter
static void predict_inter(VVCLocalContext *lc)
Definition: vvc_inter.c:911
ff_vvc_round_mv
void ff_vvc_round_mv(Mv *mv, const int lshift, const int rshift)
Definition: vvc_mvs.c:1850
CodingUnit::pred_mode
enum PredMode pred_mode
PredMode.
Definition: hevcdec.h:286
VVCLocalContext::tmp2
int16_t tmp2[MAX_PB_SIZE *MAX_PB_SIZE]
Definition: vvc_ctu.h:382
ff_vvc_gpm_weights_offset_y
const uint8_t ff_vvc_gpm_weights_offset_y[VVC_GPM_NUM_PARTITION][4][4]
Definition: vvc_data.c:2414
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
VVCLocalContext::ciip_tmp1
uint8_t ciip_tmp1[MAX_PB_SIZE *MAX_PB_SIZE *2]
Definition: vvc_ctu.h:383
BILINEAR_EXTRA_BEFORE
#define BILINEAR_EXTRA_BEFORE
Definition: vvc_ctu.h:57
pred_regular_blk
static void pred_regular_blk(VVCLocalContext *lc, const int skip_ciip)
Definition: vvc_inter.c:815
PredictionUnit::diff_mv_y
int16_t diff_mv_y[2][AFFINE_MIN_BLOCK_SIZE *AFFINE_MIN_BLOCK_SIZE]
diffMvLX
Definition: vvc_ctu.h:270
CodingUnit::next
struct CodingUnit * next
RefStruct reference.
Definition: vvc_ctu.h:325
MvField::mv
Mv mv[2]
mvL0, vvL1
Definition: hevcdec.h:301
Mv
Definition: hevcdec.h:295
MvField::ref_idx
int8_t ref_idx[2]
refIdxL0, refIdxL1
Definition: hevcdec.h:302
CTU::cus
CodingUnit * cus
Definition: vvc_ctu.h:329
subpic_offset
static void subpic_offset(int *x_off, int *y_off, const VVCSPS *sps, const VVCPPS *pps, const int subpic_idx, const int is_luma)
Definition: vvc_inter.c:33
ff_vvc_inter_luma_filters
const int8_t ff_vvc_inter_luma_filters[VVC_INTER_FILTER_TYPES][VVC_INTER_LUMA_FACTS][VVC_INTER_LUMA_TAPS]
Definition: vvc_data.c:1735
BILINEAR_EXTRA
#define BILINEAR_EXTRA
Definition: vvc_ctu.h:59
POS
#define POS(c_idx, x, y)
Definition: vvc_inter.c:495
SliceContext::sh
VVCSH sh
Definition: vvcdec.h:85
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
VVCFrameContext
Definition: vvcdec.h:92
MvField::bcw_idx
uint8_t bcw_idx
bcwIdx
Definition: vvc_ctu.h:199
pred_get_refs
static int pred_get_refs(const VVCLocalContext *lc, VVCFrame *ref[2], const MvField *mv)
Definition: vvc_inter.c:480
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
h
h
Definition: vp9dsp_template.c:2038
emulated_edge
static int emulated_edge(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 is_luma)
Definition: vvc_inter.c:47
int
int
Definition: ffmpeg_filter.c:409
CodingUnit::ciip_flag
uint8_t ciip_flag
Definition: vvc_ctu.h:299
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: vvc_inter.c:783
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
w_c
static int w_c(struct MpegEncContext *v, const uint8_t *pix1, const uint8_t *pix2, ptrdiff_t line_size, int w, int h, int type)
Definition: snow_dwt.c:744
LUMA
#define LUMA
Definition: hevc_filter.c:31
VVCLocalContext::ctb_left_flag
uint8_t ctb_left_flag
Definition: vvc_ctu.h:369
CodingUnit::y0
int y0
Definition: vvc_ctu.h:277
vvc_inter.h