FFmpeg
intra.c
Go to the documentation of this file.
1 /*
2  * VVC intra prediction
3  *
4  * Copyright (C) 2021 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 #include "libavutil/imgutils.h"
24 
25 #include "data.h"
26 #include "inter.h"
27 #include "intra.h"
28 #include "itx_1d.h"
29 
30 #define POS(c_idx, x, y) \
31  &fc->frame->data[c_idx][((y) >> fc->ps.sps->vshift[c_idx]) * fc->frame->linesize[c_idx] + \
32  (((x) >> fc->ps.sps->hshift[c_idx]) << fc->ps.sps->pixel_shift)]
33 
34 static int is_cclm(enum IntraPredMode mode)
35 {
36  return mode == INTRA_LT_CCLM || mode == INTRA_L_CCLM || mode == INTRA_T_CCLM;
37 }
38 
40 {
41  const VVCFrameContext *fc = lc->fc;
42  const VVCSPS *sps = fc->ps.sps;
43  const CodingUnit *cu = lc->cu;
44  const int x_tb = tb->x0 >> fc->ps.sps->min_cb_log2_size_y;
45  const int y_tb = tb->y0 >> fc->ps.sps->min_cb_log2_size_y;
46  const int x_c = (tb->x0 + (tb->tb_width << sps->hshift[1] >> 1) ) >> fc->ps.sps->min_cb_log2_size_y;
47  const int y_c = (tb->y0 + (tb->tb_height << sps->vshift[1] >> 1)) >> fc->ps.sps->min_cb_log2_size_y;
48  const int min_cb_width = fc->ps.pps->min_cb_width;
49  const int intra_mip_flag = SAMPLE_CTB(fc->tab.imf, x_tb, y_tb);
50  int pred_mode_intra = tb->c_idx == 0 ? cu->intra_pred_mode_y : cu->intra_pred_mode_c;
51  if (intra_mip_flag && !tb->c_idx) {
52  pred_mode_intra = INTRA_PLANAR;
53  } else if (is_cclm(pred_mode_intra)) {
54  int intra_mip_flag_c = SAMPLE_CTB(fc->tab.imf, x_c, y_c);
55  int cu_pred_mode = SAMPLE_CTB(fc->tab.cpm[0], x_c, y_c);
56  if (intra_mip_flag_c) {
57  pred_mode_intra = INTRA_PLANAR;
58  } else if (cu_pred_mode == MODE_IBC || cu_pred_mode == MODE_PLT) {
59  pred_mode_intra = INTRA_DC;
60  } else {
61  pred_mode_intra = SAMPLE_CTB(fc->tab.ipm, x_c, y_c);
62  }
63  }
64  pred_mode_intra = ff_vvc_wide_angle_mode_mapping(cu, tb->tb_width, tb->tb_height, tb->c_idx, pred_mode_intra);
65 
66  return pred_mode_intra;
67 }
68 
69 //8.7.4 Transformation process for scaled transform coefficients
70 static void ilfnst_transform(const VVCLocalContext *lc, TransformBlock *tb)
71 {
72  const VVCSPS *sps = lc->fc->ps.sps;
73  const CodingUnit *cu = lc->cu;
74  const int w = tb->tb_width;
75  const int h = tb->tb_height;
76  const int n_lfnst_out_size = (w >= 8 && h >= 8) ? 48 : 16; ///< nLfnstOutSize
77  const int log2_lfnst_size = (w >= 8 && h >= 8) ? 3 : 2; ///< log2LfnstSize
78  const int n_lfnst_size = 1 << log2_lfnst_size; ///< nLfnstSize
79  const int non_zero_size = ((w == 8 && h == 8) || (w == 4 && h == 4)) ? 8 : 16; ///< nonZeroSize
80  const int pred_mode_intra = derive_ilfnst_pred_mode_intra(lc, tb);
81  const int transpose = pred_mode_intra > 34;
82  int u[16], v[48];
83 
84  for (int x = 0; x < non_zero_size; x++) {
85  int xc = ff_vvc_diag_scan_x[2][2][x];
86  int yc = ff_vvc_diag_scan_y[2][2][x];
87  u[x] = tb->coeffs[w * yc + xc];
88  }
89  ff_vvc_inv_lfnst_1d(v, u, non_zero_size, n_lfnst_out_size, pred_mode_intra,
90  cu->lfnst_idx, sps->log2_transform_range);
91  if (transpose) {
92  int *dst = tb->coeffs;
93  const int *src = v;
94  if (n_lfnst_size == 4) {
95  for (int y = 0; y < 4; y++) {
96  dst[0] = src[0];
97  dst[1] = src[4];
98  dst[2] = src[8];
99  dst[3] = src[12];
100  src++;
101  dst += w;
102  }
103  } else {
104  for (int y = 0; y < 8; y++) {
105  dst[0] = src[0];
106  dst[1] = src[8];
107  dst[2] = src[16];
108  dst[3] = src[24];
109  if (y < 4) {
110  dst[4] = src[32];
111  dst[5] = src[36];
112  dst[6] = src[40];
113  dst[7] = src[44];
114  }
115  src++;
116  dst += w;
117  }
118  }
119 
120  } else {
121  int *dst = tb->coeffs;
122  const int *src = v;
123  for (int y = 0; y < n_lfnst_size; y++) {
124  int size = (y < 4) ? n_lfnst_size : 4;
125  memcpy(dst, src, size * sizeof(int));
126  src += size;
127  dst += w;
128  }
129  }
130  tb->max_scan_x = n_lfnst_size - 1;
131  tb->max_scan_y = n_lfnst_size - 1;
132 }
133 
134 //part of 8.7.4 Transformation process for scaled transform coefficients
135 static void derive_transform_type(const VVCFrameContext *fc, const VVCLocalContext *lc, const TransformBlock *tb, enum VVCTxType *trh, enum VVCTxType *trv)
136 {
137  const CodingUnit *cu = lc->cu;
138  static const enum VVCTxType mts_to_trh[] = { VVC_DCT2, VVC_DST7, VVC_DCT8, VVC_DST7, VVC_DCT8 };
139  static const enum VVCTxType mts_to_trv[] = { VVC_DCT2, VVC_DST7, VVC_DST7, VVC_DCT8, VVC_DCT8 };
140  const VVCSPS *sps = fc->ps.sps;
141  int implicit_mts_enabled = 0;
142  if (tb->c_idx || (cu->isp_split_type != ISP_NO_SPLIT && cu->lfnst_idx)) {
143  *trh = *trv = VVC_DCT2;
144  return;
145  }
146 
147  if (sps->r->sps_mts_enabled_flag) {
148  if (cu->isp_split_type != ISP_NO_SPLIT ||
149  (cu->sbt_flag && FFMAX(tb->tb_width, tb->tb_height) <= 32) ||
150  (!sps->r->sps_explicit_mts_intra_enabled_flag && cu->pred_mode == MODE_INTRA &&
151  !cu->lfnst_idx && !cu->intra_mip_flag)) {
152  implicit_mts_enabled = 1;
153  }
154  }
155  if (implicit_mts_enabled) {
156  const int w = tb->tb_width;
157  const int h = tb->tb_height;
158  if (cu->sbt_flag) {
159  *trh = (cu->sbt_horizontal_flag || cu->sbt_pos_flag) ? VVC_DST7 : VVC_DCT8;
160  *trv = (!cu->sbt_horizontal_flag || cu->sbt_pos_flag) ? VVC_DST7 : VVC_DCT8;
161  } else {
162  *trh = (w >= 4 && w <= 16) ? VVC_DST7 : VVC_DCT2;
163  *trv = (h >= 4 && h <= 16) ? VVC_DST7 : VVC_DCT2;
164  }
165  return;
166  }
167  *trh = mts_to_trh[cu->mts_idx];
168  *trv = mts_to_trv[cu->mts_idx];
169 }
170 
171 static int add_reconstructed_area(VVCLocalContext *lc, const int ch_type, const int x0, const int y0, const int w, const int h)
172 {
173  const VVCSPS *sps = lc->fc->ps.sps;
174  const int hs = sps->hshift[ch_type];
175  const int vs = sps->vshift[ch_type];
177 
178  if (lc->num_ras[ch_type] >= FF_ARRAY_ELEMS(lc->ras[ch_type]))
179  return AVERROR_INVALIDDATA;
180 
181  a = &lc->ras[ch_type][lc->num_ras[ch_type]];
182  a->x = x0 >> hs;
183  a->y = y0 >> vs;
184  a->w = w >> hs;
185  a->h = h >> vs;
186  lc->num_ras[ch_type]++;
187 
188  return 0;
189 }
190 
191 static void add_tu_area(const TransformUnit *tu, int *x0, int *y0, int *w, int *h)
192 {
193  *x0 = tu->x0;
194  *y0 = tu->y0;
195  *w = tu->width;
196  *h = tu->height;
197 }
198 
199 #define MIN_ISP_PRED_WIDTH 4
200 static int get_luma_predict_unit(const CodingUnit *cu, const TransformUnit *tu, const int idx, int *x0, int *y0, int *w, int *h)
201 {
202  int has_luma = 1;
203  add_tu_area(tu, x0, y0, w, h);
206  has_luma = !(idx % (MIN_ISP_PRED_WIDTH / tu->width));
207  }
208  return has_luma;
209 }
210 
211 static int get_chroma_predict_unit(const CodingUnit *cu, const TransformUnit *tu, const int idx, int *x0, int *y0, int *w, int *h)
212 {
213  if (cu->isp_split_type == ISP_NO_SPLIT) {
214  add_tu_area(tu, x0, y0, w, h);
215  return 1;
216  }
217  if (idx == cu->num_intra_subpartitions - 1) {
218  *x0 = cu->x0;
219  *y0 = cu->y0;
220  *w = cu->cb_width;
221  *h = cu->cb_height;
222  return 1;
223  }
224  return 0;
225 }
226 
227 //8.4.5.1 General decoding process for intra blocks
228 static int predict_intra(VVCLocalContext *lc, const TransformUnit *tu, const int idx, const int target_ch_type)
229 {
230  const VVCFrameContext *fc = lc->fc;
231  const CodingUnit *cu = lc->cu;
232  const VVCTreeType tree_type = cu->tree_type;
233  int x0, y0, w, h, ret;
234  if (cu->pred_mode != MODE_INTRA) {
235  ret = add_reconstructed_area(lc, target_ch_type, tu->x0, tu->y0, tu->width, tu->height);
236  return ret;
237  }
238  if (!target_ch_type && tree_type != DUAL_TREE_CHROMA) {
239  if (get_luma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)) {
240  ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
241  fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 0);
242  ret = add_reconstructed_area(lc, 0, x0, y0, w, h);
243  if (ret < 0)
244  return ret;
245  }
246  }
247  if (target_ch_type && tree_type != DUAL_TREE_LUMA) {
248  if (get_chroma_predict_unit(cu, tu, idx, &x0, &y0, &w, &h)){
249  ff_vvc_set_neighbour_available(lc, x0, y0, w, h);
250  if (is_cclm(cu->intra_pred_mode_c)) {
251  fc->vvcdsp.intra.intra_cclm_pred(lc, x0, y0, w, h);
252  } else {
253  fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 1);
254  fc->vvcdsp.intra.intra_pred(lc, x0, y0, w, h, 2);
255  }
256  ret = add_reconstructed_area(lc, 1, x0, y0, w, h);
257  if (ret < 0)
258  return ret;
259  }
260  }
261  return 0;
262 }
263 
264 static void scale_clip(int *coeff, const int nzw, const int w, const int h,
265  const int shift, const int log2_transform_range)
266 {
267  const int add = 1 << (shift - 1);
268  for (int y = 0; y < h; y++) {
269  int *p = coeff + y * w;
270  for (int x = 0; x < nzw; x++) {
271  *p = av_clip_intp2((*p + add) >> shift, log2_transform_range);
272  p++;
273  }
274  memset(p, 0, sizeof(*p) * (w - nzw));
275  }
276 }
277 
278 static void scale(int *out, const int *in, const int w, const int h, const int shift)
279 {
280  const int add = 1 << (shift - 1);
281  for (int y = 0; y < h; y++) {
282  for (int x = 0; x < w; x++) {
283  int *o = out + y * w + x;
284  const int *i = in + y * w + x;
285  *o = (*i + add) >> shift;
286  }
287  }
288 }
289 
290 // part of 8.7.3 Scaling process for transform coefficients
291 static void derive_qp(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
292 {
293  const VVCSPS *sps = lc->fc->ps.sps;
294  const H266RawSliceHeader *rsh = lc->sc->sh.r;
295  const CodingUnit *cu = lc->cu;
296  const bool is_jcbcr = tb->c_idx && tu->joint_cbcr_residual_flag && tu->coded_flag[CB] && tu->coded_flag[CR];
297  const int idx = is_jcbcr ? JCBCR : tb->c_idx;
298  const int qp = cu->qp[idx] + (idx ? 0 : sps->qp_bd_offset);
299  const int act_offset[] = { -5, 1, 3, 1 };
300  const int qp_act_offset = cu->act_enabled_flag ? act_offset[idx] : 0;
301 
302  if (tb->ts) {
303  const int qp_prime_ts_min = 4 + 6 * sps->r->sps_min_qp_prime_ts;
304 
305  tb->qp = av_clip(qp + qp_act_offset, qp_prime_ts_min, 63 + sps->qp_bd_offset);
306  tb->rect_non_ts_flag = 0;
307  tb->bd_shift = 10;
308  } else {
309  const int log_sum = tb->log2_tb_width + tb->log2_tb_height;
310  const int rect_non_ts_flag = log_sum & 1;
311 
312  tb->qp = av_clip(qp + qp_act_offset, 0, 63 + sps->qp_bd_offset);
313  tb->rect_non_ts_flag = rect_non_ts_flag;
314  tb->bd_shift = sps->bit_depth + rect_non_ts_flag + (log_sum / 2)
315  + 10 - sps->log2_transform_range + rsh->sh_dep_quant_used_flag;
316  }
317  tb->bd_offset = (1 << tb->bd_shift) >> 1;
318 }
319 
320 static const uint8_t rem6[63 + 8 * 6 + 1] = {
321  0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
322  0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
323  0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
324  0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5,
325  0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3,
326 };
327 
328 static const uint8_t div6[63 + 8 * 6 + 1] = {
329  0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
330  4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7,
331  8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11,
332  12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15,
333  16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18,
334 };
335 
336 const static int level_scale[2][6] = {
337  { 40, 45, 51, 57, 64, 72 },
338  { 57, 64, 72, 80, 90, 102 }
339 };
340 
341 //8.7.3 Scaling process for transform coefficients
342 static av_always_inline int derive_scale(const TransformBlock *tb, const int sh_dep_quant_used_flag)
343 {
344  const int addin = sh_dep_quant_used_flag && !tb->ts;
345  const int qp = tb->qp + addin;
346 
347  return level_scale[tb->rect_non_ts_flag][rem6[qp]] << div6[qp];
348 }
349 
350 //8.7.3 Scaling process for transform coefficients
351 static const uint8_t* derive_scale_m(const VVCLocalContext *lc, const TransformBlock *tb, uint8_t *scale_m)
352 {
353  //Table 38 – Specification of the scaling matrix identifier variable id according to predMode, cIdx, nTbW, and nTbH
354  const int ids[2][3][6] = {
355  {
356  { 0, 2, 8, 14, 20, 26 },
357  { 0, 3, 9, 15, 21, 21 },
358  { 0, 4, 10, 16, 22, 22 }
359  },
360  {
361  { 0, 5, 11, 17, 23, 27 },
362  { 0, 6, 12, 18, 24, 24 },
363  { 1, 7, 13, 19, 25, 25 },
364  }
365  };
366  const VVCFrameParamSets *ps = &lc->fc->ps;
367  const VVCSPS *sps = ps->sps;
368  const H266RawSliceHeader *rsh = lc->sc->sh.r;
369  const CodingUnit *cu = lc->cu;
370  const VVCScalingList *sl = ps->sl;
371  const int id = ids[cu->pred_mode != MODE_INTRA][tb->c_idx][FFMAX(tb->log2_tb_height, tb->log2_tb_width) - 1];
372  const int log2_matrix_size = (id < 2) ? 1 : (id < 8) ? 2 : 3;
373  uint8_t *p = scale_m;
374 
375  if (!rsh->sh_explicit_scaling_list_used_flag || tb->ts ||
376  (sps->r->sps_scaling_matrix_for_lfnst_disabled_flag && cu->apply_lfnst_flag[tb->c_idx]) ||
377  (sps->r->sps_scaling_matrix_for_alternative_colour_space_disabled_flag &&
378  sps->r->sps_scaling_matrix_designated_colour_space_flag == cu->act_enabled_flag))
379  return ff_vvc_default_scale_m;
380 
381  if (!sl) {
382  av_log(lc->fc->log_ctx, AV_LOG_WARNING, "bug: no scaling list aps, id = %d", ps->ph.r->ph_scaling_list_aps_id);
383  return ff_vvc_default_scale_m;
384  }
385 
386  for (int y = tb->min_scan_y; y <= tb->max_scan_y; y++) {
387  const int off = y << log2_matrix_size >> tb->log2_tb_height << log2_matrix_size;
388  const uint8_t *m = &sl->scaling_matrix_rec[id][off];
389 
390  for (int x = tb->min_scan_x; x <= tb->max_scan_x; x++)
391  *p++ = m[x << log2_matrix_size >> tb->log2_tb_width];
392  }
393  if (id >= SL_START_16x16 && !tb->min_scan_x && !tb->min_scan_y)
394  *scale_m = sl->scaling_matrix_dc_rec[id - SL_START_16x16];
395 
396  return scale_m;
397 }
398 
399 //8.7.3 Scaling process for transform coefficients
401  const int scale, const int scale_m, const int log2_transform_range)
402 {
403  coeff = ((int64_t) coeff * scale * scale_m + tb->bd_offset) >> tb->bd_shift;
404  coeff = av_clip_intp2(coeff, log2_transform_range);
405  return coeff;
406 }
407 
408 static void dequant(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
409 {
410  uint8_t tmp[MAX_TB_SIZE * MAX_TB_SIZE];
411  const H266RawSliceHeader *rsh = lc->sc->sh.r;
412  const VVCSPS *sps = lc->fc->ps.sps;
413  const uint8_t *scale_m = derive_scale_m(lc, tb, tmp);
414  int scale;
415 
416  derive_qp(lc, tu, tb);
418 
419  for (int y = tb->min_scan_y; y <= tb->max_scan_y; y++) {
420  for (int x = tb->min_scan_x; x <= tb->max_scan_x; x++) {
421  int *coeff = tb->coeffs + y * tb->tb_width + x;
422 
423  if (*coeff)
424  *coeff = scale_coeff(tb, *coeff, scale, *scale_m, sps->log2_transform_range);
425  scale_m++;
426  }
427  }
428 }
429 
430 //transmatrix[0][0]
431 #define DCT_A 64
432 static void itx_2d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
433 {
434  const VVCSPS *sps = fc->ps.sps;
435  const int w = tb->tb_width;
436  const int h = tb->tb_height;
437  const size_t nzw = tb->max_scan_x + 1;
438  const size_t nzh = tb->max_scan_y + 1;
439  const int shift[] = { 7, 5 + sps->log2_transform_range - sps->bit_depth };
440 
441  if (w == h && nzw == 1 && nzh == 1 && trh == VVC_DCT2 && trv == VVC_DCT2) {
442  const int add[] = { 1 << (shift[0] - 1), 1 << (shift[1] - 1) };
443  const int t = (tb->coeffs[0] * DCT_A + add[0]) >> shift[0];
444  const int dc = (t * DCT_A + add[1]) >> shift[1];
445 
446  for (int i = 0; i < w * h; i++)
447  tb->coeffs[i] = dc;
448 
449  return;
450  }
451 
452  for (int x = 0; x < nzw; x++)
453  fc->vvcdsp.itx.itx[trv][tb->log2_tb_height - 1](tb->coeffs + x, w, nzh);
454  scale_clip(tb->coeffs, nzw, w, h, shift[0], sps->log2_transform_range);
455 
456  for (int y = 0; y < h; y++)
457  fc->vvcdsp.itx.itx[trh][tb->log2_tb_width - 1](tb->coeffs + y * w, 1, nzw);
458  scale(tb->coeffs, tb->coeffs, w, h, shift[1]);
459 }
460 
461 static void itx_1d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
462 {
463  const VVCSPS *sps = fc->ps.sps;
464  const int w = tb->tb_width;
465  const int h = tb->tb_height;
466  const size_t nzw = tb->max_scan_x + 1;
467  const size_t nzh = tb->max_scan_y + 1;
468 
469  if ((w > 1 && nzw == 1 && trh == VVC_DCT2) || (h > 1 && nzh == 1 && trv == VVC_DCT2)) {
470  const int shift = 6 + sps->log2_transform_range - sps->bit_depth;
471  const int add = 1 << (shift - 1);
472  const int dc = (tb->coeffs[0] * DCT_A + add) >> shift;
473 
474  for (int i = 0; i < w * h; i++)
475  tb->coeffs[i] = dc;
476 
477  return;
478  }
479 
480  if (w > 1)
481  fc->vvcdsp.itx.itx[trh][tb->log2_tb_width - 1](tb->coeffs, 1, nzw);
482  else
483  fc->vvcdsp.itx.itx[trv][tb->log2_tb_height - 1](tb->coeffs, 1, nzh);
484  scale(tb->coeffs, tb->coeffs, w, h, 6 + sps->log2_transform_range - sps->bit_depth);
485 }
486 
487 static void transform_bdpcm(TransformBlock *tb, const VVCLocalContext *lc, const CodingUnit *cu)
488 {
489  const VVCSPS *sps = lc->fc->ps.sps;
491  const int vertical = mode == INTRA_VERT;
492  lc->fc->vvcdsp.itx.transform_bdpcm(tb->coeffs, tb->tb_width, tb->tb_height,
493  vertical, sps->log2_transform_range);
494  if (vertical)
495  tb->max_scan_y = tb->tb_height - 1;
496  else
497  tb->max_scan_x = tb->tb_width - 1;
498 }
499 
500 static void lmcs_scale_chroma(VVCLocalContext *lc, TransformUnit *tu, TransformBlock *tb, const int target_ch_type)
501 {
502  const VVCFrameContext *fc = lc->fc;
503  const VVCSH *sh = &lc->sc->sh;
504  const CodingUnit *cu = lc->cu;
505  const int c_idx = tb->c_idx;
506  const int ch_type = c_idx > 0;
507  const int w = tb->tb_width;
508  const int h = tb->tb_height;
509  const int chroma_scale = ch_type && sh->r->sh_lmcs_used_flag && fc->ps.ph.r->ph_chroma_residual_scale_flag && (w * h > 4);
510  const int has_jcbcr = tu->joint_cbcr_residual_flag && c_idx;
511 
512  for (int j = 0; j < 1 + has_jcbcr; j++) {
513  const bool is_jcbcr = j > 0;
514  const int jcbcr_idx = CB + tu->coded_flag[CB];
515  TransformBlock *jcbcr = &tu->tbs[jcbcr_idx - tu->tbs[0].c_idx];
516  int *coeffs = is_jcbcr ? jcbcr->coeffs : tb->coeffs;
517 
518  if (!j && has_jcbcr) {
519  const int c_sign = 1 - 2 * fc->ps.ph.r->ph_joint_cbcr_sign_flag;
520  const int shift = tu->coded_flag[CB] ^ tu->coded_flag[CR];
521  fc->vvcdsp.itx.pred_residual_joint(jcbcr->coeffs, tb->coeffs, w, h, c_sign, shift);
522  }
523  if (chroma_scale)
524  fc->vvcdsp.intra.lmcs_scale_chroma(lc, coeffs, w, h, cu->x0, cu->y0);
525  }
526 }
527 
528 static void add_residual(const VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
529 {
530  const VVCFrameContext *fc = lc->fc;
531  const CodingUnit *cu = lc->cu;
532 
533  for (int i = 0; i < tu->nb_tbs; i++) {
534  TransformBlock *tb = tu->tbs + i;
535  const int c_idx = tb->c_idx;
536  const int ch_type = c_idx > 0;
537  const ptrdiff_t stride = fc->frame->linesize[c_idx];
538  const bool has_residual = tb->has_coeffs || cu->act_enabled_flag ||
539  (c_idx && tu->joint_cbcr_residual_flag);
540  uint8_t *dst = POS(c_idx, tb->x0, tb->y0);
541 
542  if (ch_type == target_ch_type && has_residual)
543  fc->vvcdsp.itx.add_residual(dst, tb->coeffs, tb->tb_width, tb->tb_height, stride);
544  }
545 }
546 
547 static void itransform(VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
548 {
549  const VVCFrameContext *fc = lc->fc;
550  const CodingUnit *cu = lc->cu;
551  TransformBlock *tbs = tu->tbs;
552  const bool is_act_luma = cu->act_enabled_flag && target_ch_type == LUMA;
553 
554  for (int i = 0; i < tu->nb_tbs; i++) {
555  TransformBlock *tb = tbs + i;
556  const int c_idx = tb->c_idx;
557  const int ch_type = c_idx > 0;
558  const bool do_itx = is_act_luma || !cu->act_enabled_flag && ch_type == target_ch_type;
559 
560  if (tb->has_coeffs && do_itx) {
561  if (cu->bdpcm_flag[tb->c_idx])
562  transform_bdpcm(tb, lc, cu);
563  dequant(lc, tu, tb);
564  if (!tb->ts) {
565  enum VVCTxType trh, trv;
566 
567  if (cu->apply_lfnst_flag[c_idx])
568  ilfnst_transform(lc, tb);
569  derive_transform_type(fc, lc, tb, &trh, &trv);
570  if (tb->tb_width > 1 && tb->tb_height > 1)
571  itx_2d(fc, tb, trh, trv);
572  else
573  itx_1d(fc, tb, trh, trv);
574  }
575  lmcs_scale_chroma(lc, tu, tb, target_ch_type);
576  }
577  }
578 
579  if (is_act_luma) {
580  fc->vvcdsp.itx.adaptive_color_transform(
581  tbs[LUMA].coeffs, tbs[CB].coeffs, tbs[CR].coeffs,
582  tbs[LUMA].tb_width, tbs[LUMA].tb_height);
583  }
584 
585  add_residual(lc, tu, target_ch_type);
586 }
587 
589 {
590  VVCFrameContext *fc = lc->fc;
591  CodingUnit *cu = lc->cu;
592  const int start = cu->tree_type == DUAL_TREE_CHROMA;
593  const int end = fc->ps.sps->r->sps_chroma_format_idc && (cu->tree_type != DUAL_TREE_LUMA);
594  int ret;
595 
596  for (int ch_type = start; ch_type <= end; ch_type++) {
597  TransformUnit *tu = cu->tus.head;
598  for (int i = 0; tu; i++) {
599  ret = predict_intra(lc, tu, i, ch_type);
600  if (ret < 0)
601  return ret;
602  itransform(lc, tu, ch_type);
603  tu = tu->next;
604  }
605  }
606  return 0;
607 }
608 
609 #define IBC_POS(c_idx, x, y) \
610  (fc->tab.ibc_vir_buf[c_idx] + \
611  (x << ps) + (y + ((cu->y0 & ~(sps->ctb_size_y - 1)) >> vs)) * ibc_stride)
612 #define IBC_X(x) ((x) & ((fc->tab.sz.ibc_buffer_width >> hs) - 1))
613 #define IBC_Y(y) ((y) & ((1 << sps->ctb_log2_size_y >> vs) - 1))
614 
615 static void intra_block_copy(const VVCLocalContext *lc, const int c_idx)
616 {
617  const CodingUnit *cu = lc->cu;
618  const PredictionUnit *pu = &cu->pu;
619  const VVCFrameContext *fc = lc->fc;
620  const VVCSPS *sps = fc->ps.sps;
621  const Mv *bv = &pu->mi.mv[L0][0];
622  const int hs = sps->hshift[c_idx];
623  const int vs = sps->vshift[c_idx];
624  const int ps = sps->pixel_shift;
625  const int ref_x = IBC_X((cu->x0 >> hs) + (bv->x >> (4 + hs)));
626  const int ref_y = IBC_Y((cu->y0 >> vs) + (bv->y >> (4 + vs)));
627  const int w = cu->cb_width >> hs;
628  const int h = cu->cb_height >> vs;
629  const int ibc_buf_width = fc->tab.sz.ibc_buffer_width >> hs; ///< IbcBufWidthY and IbcBufWidthC
630  const int rw = FFMIN(w, ibc_buf_width - ref_x);
631  const int ibc_stride = ibc_buf_width << ps;
632  const int dst_stride = fc->frame->linesize[c_idx];
633  const uint8_t *ibc_buf = IBC_POS(c_idx, ref_x, ref_y);
634  uint8_t *dst = POS(c_idx, cu->x0, cu->y0);
635 
636  av_image_copy_plane(dst, dst_stride, ibc_buf, ibc_stride, rw << ps, h);
637 
638  if (w > rw) {
639  //wrap around, left part
640  ibc_buf = IBC_POS(c_idx, 0, ref_y);
641  dst += rw << ps;
642  av_image_copy_plane(dst, dst_stride, ibc_buf, ibc_stride, (w - rw) << ps, h);
643  }
644 }
645 
646 static void vvc_predict_ibc(const VVCLocalContext *lc)
647 {
648  const H266RawSPS *rsps = lc->fc->ps.sps->r;
649 
650  intra_block_copy(lc, LUMA);
651  if (lc->cu->tree_type == SINGLE_TREE && rsps->sps_chroma_format_idc) {
652  intra_block_copy(lc, CB);
653  intra_block_copy(lc, CR);
654  }
655 }
656 
657 static void ibc_fill_vir_buf(const VVCLocalContext *lc, const CodingUnit *cu)
658 {
659  const VVCFrameContext *fc = lc->fc;
660  const VVCSPS *sps = fc->ps.sps;
661  int start, end;
662 
663  ff_vvc_channel_range(&start, &end, cu->tree_type, sps->r->sps_chroma_format_idc);
664 
665  for (int c_idx = start; c_idx < end; c_idx++) {
666  const int hs = sps->hshift[c_idx];
667  const int vs = sps->vshift[c_idx];
668  const int ps = sps->pixel_shift;
669  const int x = IBC_X(cu->x0 >> hs);
670  const int y = IBC_Y(cu->y0 >> vs);
671  const int src_stride = fc->frame->linesize[c_idx];
672  const int ibc_stride = fc->tab.sz.ibc_buffer_width >> hs << ps;
673  const uint8_t *src = POS(c_idx, cu->x0, cu->y0);
674  uint8_t *ibc_buf = IBC_POS(c_idx, x, y);
675 
676  av_image_copy_plane(ibc_buf, ibc_stride, src, src_stride, cu->cb_width >> hs << ps , cu->cb_height >> vs);
677  }
678 }
679 
681 {
682  const VVCSPS *sps = lc->fc->ps.sps;
683  const int qp_prime_ts_min = 4 + 6 * sps->r->sps_min_qp_prime_ts;
684  int qp;
685 
686  derive_qp(lc, tu, tb);
687  qp = FFMAX(qp_prime_ts_min, tb->qp);
688  return level_scale[0][rem6[qp]] << div6[qp];
689 }
690 
691 // 8.4.5.3 Decoding process for palette mode
693 {
694  const VVCFrameContext *fc = lc->fc;
695  const CodingUnit *cu = lc->cu;
696  TransformUnit *tu = cu->tus.head;
697  const VVCSPS *sps = fc->ps.sps;
698  const int ps = sps->pixel_shift;
699 
700  for (int i = 0; i < tu->nb_tbs; i++) {
701  TransformBlock *tb = &tu->tbs[i];
702  const int c_idx = tb->c_idx;
703  const int w = tb->tb_width;
704  const int h = tb->tb_height;
705  const ptrdiff_t stride = fc->frame->linesize[c_idx];
706  uint8_t *dst = POS(c_idx, cu->x0, cu->y0);
707 
708  av_image_copy_plane(dst, stride, (uint8_t*)tb->coeffs, w << ps, w << ps, h);
709  }
710 }
711 
712 int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const int ry)
713 {
714  const VVCFrameContext *fc = lc->fc;
715  const VVCSPS *sps = fc->ps.sps;
716  const int x_ctb = rx << sps->ctb_log2_size_y;
717  const int y_ctb = ry << sps->ctb_log2_size_y;
718  CodingUnit *cu = fc->tab.cus[rs];
719  int ret = 0;
720 
721  lc->num_ras[0] = lc->num_ras[1] = 0;
722  lc->lmcs.x_vpdu = -1;
723  lc->lmcs.y_vpdu = -1;
724  ff_vvc_decode_neighbour(lc, x_ctb, y_ctb, rx, ry, rs);
725  while (cu) {
726  lc->cu = cu;
727 
728  if (cu->ciip_flag)
730  else if (cu->pred_mode == MODE_IBC)
731  vvc_predict_ibc(lc);
732  else if (cu->pred_mode == MODE_PLT)
734  if (cu->coded_flag) {
735  ret = reconstruct(lc);
736  } else {
737  if (cu->tree_type != DUAL_TREE_CHROMA) {
738  ret = add_reconstructed_area(lc, LUMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
739  if (ret < 0)
740  return ret;
741  }
742  if (sps->r->sps_chroma_format_idc && cu->tree_type != DUAL_TREE_LUMA) {
743  ret = add_reconstructed_area(lc, CHROMA, cu->x0, cu->y0, cu->cb_width, cu->cb_height);
744  if (ret < 0)
745  return ret;
746  }
747  }
748  if (sps->r->sps_ibc_enabled_flag)
749  ibc_fill_vir_buf(lc, cu);
750  cu = cu->next;
751  }
752  ff_vvc_ctu_free_cus(fc->tab.cus + rs);
753  return ret;
754 }
ff_vvc_reconstruct
int ff_vvc_reconstruct(VVCLocalContext *lc, const int rs, const int rx, const int ry)
reconstruct a CTU
Definition: intra.c:712
VVCSPS
Definition: ps.h:58
get_luma_predict_unit
static int get_luma_predict_unit(const CodingUnit *cu, const TransformUnit *tu, const int idx, int *x0, int *y0, int *w, int *h)
Definition: intra.c:200
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
derive_ilfnst_pred_mode_intra
static int derive_ilfnst_pred_mode_intra(const VVCLocalContext *lc, const TransformBlock *tb)
Definition: intra.c:39
VVC_DCT8
@ VVC_DCT8
Definition: dsp.h:33
av_clip
#define av_clip
Definition: common.h:100
LUMA
#define LUMA
Definition: filter.c:31
TransformBlock::tb_width
int tb_width
Definition: ctu.h:149
MotionInfo::mv
Mv mv[2][MAX_CONTROL_POINTS]
Definition: ctu.h:251
H266RawSliceHeader::sh_explicit_scaling_list_used_flag
uint8_t sh_explicit_scaling_list_used_flag
Definition: cbs_h266.h:795
out
FILE * out
Definition: movenc.c:55
TransformUnit::height
int height
Definition: ctu.h:177
CB
#define CB
Definition: filter.c:32
vvc_predict_ibc
static void vvc_predict_ibc(const VVCLocalContext *lc)
Definition: intra.c:646
INTRA_T_CCLM
@ INTRA_T_CCLM
Definition: ctu.h:241
CodingUnit
Definition: hevcdec.h:290
int64_t
long long int64_t
Definition: coverity.c:34
CodingUnit::act_enabled_flag
uint8_t act_enabled_flag
Definition: ctu.h:305
VVC_DCT2
@ VVC_DCT2
Definition: dsp.h:31
CodingUnit::head
TransformUnit * head
RefStruct reference.
Definition: ctu.h:330
TransformUnit::nb_tbs
uint8_t nb_tbs
Definition: ctu.h:183
CodingUnit::bdpcm_flag
int bdpcm_flag[VVC_MAX_SAMPLE_ARRAYS]
BdpcmFlag.
Definition: ctu.h:325
TransformBlock::min_scan_y
int min_scan_y
Definition: ctu.h:157
MODE_IBC
@ MODE_IBC
Definition: ctu.h:194
scale_clip
static void scale_clip(int *coeff, const int nzw, const int w, const int h, const int shift, const int log2_transform_range)
Definition: intra.c:264
data.h
scale_coeff
static av_always_inline int scale_coeff(const TransformBlock *tb, int coeff, const int scale, const int scale_m, const int log2_transform_range)
Definition: intra.c:400
mode
Definition: swscale.c:56
u
#define u(width, name, range_min, range_max)
Definition: cbs_apv.c:68
level_scale
const static int level_scale[2][6]
Definition: intra.c:336
CodingUnit::intra_mip_flag
uint8_t intra_mip_flag
intra_mip_flag
Definition: ctu.h:308
VVCLocalContext::sc
SliceContext * sc
Definition: ctu.h:445
INTRA_DC
@ INTRA_DC
Definition: hevcdec.h:126
itx_1d
static void itx_1d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
Definition: intra.c:461
Mv::y
int16_t y
vertical component of motion vector
Definition: hevcdec.h:305
TransformUnit::x0
int x0
Definition: ctu.h:174
VVCSH::r
const H266RawSliceHeader * r
RefStruct reference.
Definition: ps.h:239
VVCDSPContext::itx
VVCItxDSPContext itx
Definition: dsp.h:173
TransformBlock::min_scan_x
int min_scan_x
Definition: ctu.h:156
ReconstructedArea
Definition: ctu.h:349
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
add_residual
static void add_residual(const VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
Definition: intra.c:528
add_tu_area
static void add_tu_area(const TransformUnit *tu, int *x0, int *y0, int *w, int *h)
Definition: intra.c:191
TransformBlock::max_scan_y
int max_scan_y
Definition: ctu.h:155
VVCLocalContext::ras
ReconstructedArea ras[2][MAX_PARTS_IN_CTU]
Definition: ctu.h:430
ff_vvc_channel_range
void ff_vvc_channel_range(int *start, int *end, const VVCTreeType tree_type, const uint8_t chroma_format_idc)
Definition: ctu.c:2923
TransformBlock::max_scan_x
int max_scan_x
Definition: ctu.h:154
av_image_copy_plane
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:374
div6
static const uint8_t div6[63+8 *6+1]
Definition: intra.c:328
JCBCR
#define JCBCR
Definition: dec.h:39
VVCFrameParamSets::sps
const VVCSPS * sps
RefStruct reference.
Definition: ps.h:230
VVCFrameParamSets
Definition: ps.h:229
VVCLocalContext::fc
VVCFrameContext * fc
Definition: ctu.h:446
PredictionUnit
Definition: hevcdec.h:323
CodingUnit::apply_lfnst_flag
int apply_lfnst_flag[VVC_MAX_SAMPLE_ARRAYS]
ApplyLfnstFlag[].
Definition: ctu.h:327
TransformBlock::c_idx
uint8_t c_idx
Definition: ctu.h:144
CodingUnit::sbt_pos_flag
uint8_t sbt_pos_flag
Definition: ctu.h:300
IBC_POS
#define IBC_POS(c_idx, x, y)
Definition: intra.c:609
TransformBlock::x0
int x0
Definition: ctu.h:146
VVCFrameParamSets::sl
const VVCScalingList * sl
RefStruct reference.
Definition: ps.h:235
VVCLocalContext::lmcs
struct VVCLocalContext::@337 lmcs
ISP_VER_SPLIT
@ ISP_VER_SPLIT
Definition: ctu.h:122
CodingUnit::cb_width
int cb_width
Definition: ctu.h:291
get_chroma_predict_unit
static int get_chroma_predict_unit(const CodingUnit *cu, const TransformUnit *tu, const int idx, int *x0, int *y0, int *w, int *h)
Definition: intra.c:211
CodingUnit::pu
PredictionUnit pu
Definition: ctu.h:338
H266RawSPS::sps_chroma_format_idc
uint8_t sps_chroma_format_idc
Definition: cbs_h266.h:314
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
TransformBlock::y0
int y0
Definition: ctu.h:147
TransformUnit::next
struct TransformUnit * next
RefStruct reference.
Definition: ctu.h:186
derive_scale
static av_always_inline int derive_scale(const TransformBlock *tb, const int sh_dep_quant_used_flag)
Definition: intra.c:342
reconstruct
static int reconstruct(VVCLocalContext *lc)
Definition: intra.c:588
fc
#define fc(width, name, range_min, range_max)
Definition: cbs_av1.c:494
VVCSH
Definition: ps.h:238
POS
#define POS(c_idx, x, y)
Definition: intra.c:30
CodingUnit::tree_type
VVCTreeType tree_type
Definition: ctu.h:288
VVCFrameParamSets::ph
VVCPH ph
Definition: ps.h:232
CodingUnit::mts_idx
MtsIdx mts_idx
Definition: ctu.h:303
TransformUnit::coded_flag
uint8_t coded_flag[VVC_MAX_SAMPLE_ARRAYS]
tu_y_coded_flag, tu_cb_coded_flag, tu_cr_coded_flag
Definition: ctu.h:182
VVCLocalContext::num_ras
int num_ras[2]
Definition: ctu.h:431
ff_vvc_default_scale_m
uint8_t ff_vvc_default_scale_m[64 *64]
Definition: data.c:1641
VVCFrameContext::log_ctx
void * log_ctx
Definition: dec.h:123
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
ilfnst_transform
static void ilfnst_transform(const VVCLocalContext *lc, TransformBlock *tb)
Definition: intra.c:70
H266RawSliceHeader::sh_lmcs_used_flag
uint8_t sh_lmcs_used_flag
Definition: cbs_h266.h:794
H266RawSPS
Definition: cbs_h266.h:308
DCT_A
#define DCT_A
Definition: intra.c:431
ff_vvc_palette_derive_scale
int ff_vvc_palette_derive_scale(VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
Definition: intra.c:680
CodingUnit::sbt_flag
uint8_t sbt_flag
Definition: ctu.h:298
inter.h
VVCTreeType
VVCTreeType
Definition: ctu.h:167
av_clip_intp2
#define av_clip_intp2
Definition: common.h:121
TransformBlock::rect_non_ts_flag
int rect_non_ts_flag
Definition: ctu.h:160
VVCLocalContext
Definition: ctu.h:384
VVCFrameContext::vvcdsp
VVCDSPContext vvcdsp
Definition: dec.h:140
CodingUnit::tus
struct CodingUnit::@335 tus
lmcs_scale_chroma
static void lmcs_scale_chroma(VVCLocalContext *lc, TransformUnit *tu, TransformBlock *tb, const int target_ch_type)
Definition: intra.c:500
H266RawSliceHeader::sh_dep_quant_used_flag
uint8_t sh_dep_quant_used_flag
Definition: cbs_h266.h:824
TransformBlock::log2_tb_width
int log2_tb_width
Definition: ctu.h:151
transform_bdpcm
static void transform_bdpcm(TransformBlock *tb, const VVCLocalContext *lc, const CodingUnit *cu)
Definition: intra.c:487
L0
#define L0
Definition: hevcdec.h:56
itransform
static void itransform(VVCLocalContext *lc, TransformUnit *tu, const int target_ch_type)
Definition: intra.c:547
Mv::x
int16_t x
horizontal component of motion vector
Definition: hevcdec.h:304
VVCPH::r
const H266RawPictureHeader * r
Definition: ps.h:148
VVCItxDSPContext::transform_bdpcm
void(* transform_bdpcm)(int *coeffs, int width, int height, int vertical, int log2_transform_range)
Definition: dsp.h:128
ff_vvc_diag_scan_y
const uint8_t ff_vvc_diag_scan_y[5][5][16 *16]
Definition: data.c:152
SAMPLE_CTB
#define SAMPLE_CTB(tab, x, y)
Definition: hevcdec.h:72
TransformUnit
Definition: hevcdec.h:333
DUAL_TREE_LUMA
@ DUAL_TREE_LUMA
Definition: ctu.h:169
derive_qp
static void derive_qp(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
Definition: intra.c:291
TransformBlock::bd_offset
int bd_offset
Definition: ctu.h:162
ff_vvc_decode_neighbour
void ff_vvc_decode_neighbour(VVCLocalContext *lc, const int x_ctb, const int y_ctb, const int rx, const int ry, const int rs)
Definition: ctu.c:2839
VVCScalingList
Definition: ps.h:196
TransformBlock::tb_height
int tb_height
Definition: ctu.h:150
TransformBlock::ts
uint8_t ts
transform_skip_flag
Definition: ctu.h:145
dc
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 top and top right vectors is used as motion vector prediction the used motion vector is the sum of the predictor and(mvx_diff, mvy_diff) *mv_scale Intra DC Prediction block[y][x] dc[1]
Definition: snow.txt:400
IBC_Y
#define IBC_Y(y)
Definition: intra.c:613
CodingUnit::intra_pred_mode_y
IntraPredMode intra_pred_mode_y
IntraPredModeY.
Definition: ctu.h:321
shift
static int shift(int a, int b)
Definition: bonk.c:261
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
derive_transform_type
static void derive_transform_type(const VVCFrameContext *fc, const VVCLocalContext *lc, const TransformBlock *tb, enum VVCTxType *trh, enum VVCTxType *trv)
Definition: intra.c:135
INTRA_PLANAR
@ INTRA_PLANAR
Definition: hevcdec.h:125
size
int size
Definition: twinvq_data.h:10344
CodingUnit::sbt_horizontal_flag
uint8_t sbt_horizontal_flag
Definition: ctu.h:299
intra.h
H266RawPictureHeader::ph_scaling_list_aps_id
uint8_t ph_scaling_list_aps_id
Definition: cbs_h266.h:704
frame.h
CodingUnit::coded_flag
uint8_t coded_flag
Definition: ctu.h:296
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
CodingUnit::lfnst_idx
int lfnst_idx
Definition: ctu.h:302
VVCScalingList::scaling_matrix_dc_rec
uint8_t scaling_matrix_dc_rec[SL_MAX_ID - SL_START_16x16]
ScalingMatrixDcRec[refId − 14].
Definition: ps.h:198
add_reconstructed_area
static int add_reconstructed_area(VVCLocalContext *lc, const int ch_type, const int x0, const int y0, const int w, const int h)
Definition: intra.c:171
ff_vvc_predict_ciip
void ff_vvc_predict_ciip(VVCLocalContext *lc)
CIIP(Combined Inter-Intra Prediction) for a coding block.
Definition: inter.c:1018
CodingUnit::intra_pred_mode_c
IntraPredMode intra_pred_mode_c
IntraPredModeC.
Definition: ctu.h:322
itx_1d.h
dequant
static void dequant(const VVCLocalContext *lc, const TransformUnit *tu, TransformBlock *tb)
Definition: intra.c:408
H266RawSliceHeader
Definition: cbs_h266.h:771
PredictionUnit::mi
MotionInfo mi
Definition: ctu.h:271
MODE_INTRA
#define MODE_INTRA
Definition: vp3.c:84
CR
#define CR
Definition: filter.c:33
MODE_PLT
@ MODE_PLT
Definition: ctu.h:193
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
ISP_NO_SPLIT
@ ISP_NO_SPLIT
Definition: ctu.h:120
SL_START_16x16
@ SL_START_16x16
Definition: ps.h:188
ff_vvc_diag_scan_x
const uint8_t ff_vvc_diag_scan_x[5][5][16 *16]
Definition: data.c:27
rem6
static const uint8_t rem6[63+8 *6+1]
Definition: intra.c:320
MIN_ISP_PRED_WIDTH
#define MIN_ISP_PRED_WIDTH
Definition: intra.c:199
av_always_inline
#define av_always_inline
Definition: attributes.h:63
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
CodingUnit::x0
int x0
Definition: ctu.h:289
TransformUnit::tbs
TransformBlock tbs[VVC_MAX_SAMPLE_ARRAYS]
Definition: ctu.h:184
TransformBlock::coeffs
int * coeffs
Definition: ctu.h:164
TransformBlock::bd_shift
int bd_shift
Definition: ctu.h:161
itx_2d
static void itx_2d(const VVCFrameContext *fc, TransformBlock *tb, const enum VVCTxType trh, const enum VVCTxType trv)
Definition: intra.c:432
TransformUnit::width
int width
Definition: ctu.h:176
VVCLocalContext::cu
CodingUnit * cu
Definition: ctu.h:429
ff_vvc_wide_angle_mode_mapping
int ff_vvc_wide_angle_mode_mapping(const CodingUnit *cu, int tb_width, int tb_height, int c_idx, int pred_mode_intra)
Definition: intra_utils.c:197
INTRA_VERT
@ INTRA_VERT
Definition: ctu.h:237
ret
ret
Definition: filter_design.txt:187
IntraPredMode
IntraPredMode
Definition: hevcdec.h:124
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
id
enum AVCodecID id
Definition: dts2pts.c:549
CodingUnit::cb_height
int cb_height
Definition: ctu.h:292
TransformBlock::log2_tb_height
int log2_tb_height
Definition: ctu.h:152
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
TransformBlock::has_coeffs
uint8_t has_coeffs
Definition: ctu.h:143
INTRA_L_CCLM
@ INTRA_L_CCLM
Definition: ctu.h:240
TransformBlock
Definition: ctu.h:142
CodingUnit::pred_mode
enum PredMode pred_mode
PredMode.
Definition: hevcdec.h:294
ff_vvc_inv_lfnst_1d
void ff_vvc_inv_lfnst_1d(int *v, const int *u, int no_zero_size, int n_tr_s, int pred_mode_intra, int lfnst_idx, int log2_transform_range)
Definition: itx_1d.c:695
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
intra_block_copy
static void intra_block_copy(const VVCLocalContext *lc, const int c_idx)
Definition: intra.c:615
TransformUnit::y0
int y0
Definition: ctu.h:175
CodingUnit::next
struct CodingUnit * next
RefStruct reference.
Definition: ctu.h:340
Mv
Definition: hevcdec.h:303
predict_intra
static int predict_intra(VVCLocalContext *lc, const TransformUnit *tu, const int idx, const int target_ch_type)
Definition: intra.c:228
VVCFrameContext::ps
VVCFrameParamSets ps
Definition: dec.h:131
VVCLocalContext::x_vpdu
int x_vpdu
Definition: ctu.h:425
w
uint8_t w
Definition: llvidencdsp.c:39
SINGLE_TREE
@ SINGLE_TREE
Definition: ctu.h:168
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:278
VVCLocalContext::y_vpdu
int y_vpdu
Definition: ctu.h:426
VVCSPS::r
const H266RawSPS * r
RefStruct reference.
Definition: ps.h:59
SliceContext::sh
VVCSH sh
Definition: dec.h:115
TransformBlock::qp
int qp
Definition: ctu.h:159
CodingUnit::isp_split_type
enum IspType isp_split_type
IntraSubPartitionsSplitType.
Definition: ctu.h:315
VVCFrameContext
Definition: dec.h:122
VVCTxType
VVCTxType
Definition: dsp.h:30
imgutils.h
VVC_DST7
@ VVC_DST7
Definition: dsp.h:32
coeff
static const double coeff[2][5]
Definition: vf_owdenoise.c:80
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
vvc_predict_palette
static void vvc_predict_palette(VVCLocalContext *lc)
Definition: intra.c:692
MAX_TB_SIZE
#define MAX_TB_SIZE
Definition: hevcdec.h:47
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
TransformUnit::joint_cbcr_residual_flag
uint8_t joint_cbcr_residual_flag
tu_joint_cbcr_residual_flag
Definition: ctu.h:180
h
h
Definition: vp9dsp_template.c:2070
ibc_fill_vir_buf
static void ibc_fill_vir_buf(const VVCLocalContext *lc, const CodingUnit *cu)
Definition: intra.c:657
stride
#define stride
Definition: h264pred_template.c:536
transpose
#define transpose(x)
INTRA_LT_CCLM
@ INTRA_LT_CCLM
Definition: ctu.h:239
CodingUnit::ciip_flag
uint8_t ciip_flag
Definition: ctu.h:312
IBC_X
#define IBC_X(x)
Definition: intra.c:612
src
#define src
Definition: vp8dsp.c:248
CodingUnit::num_intra_subpartitions
int num_intra_subpartitions
Definition: ctu.h:319
VVCScalingList::scaling_matrix_rec
uint8_t scaling_matrix_rec[SL_MAX_ID][SL_MAX_MATRIX_SIZE *SL_MAX_MATRIX_SIZE]
ScalingMatrixRec.
Definition: ps.h:197
CodingUnit::y0
int y0
Definition: ctu.h:290
CodingUnit::qp
int8_t qp[4]
QpY, Qp′Cb, Qp′Cr, Qp′CbCr.
Definition: ctu.h:334
derive_scale_m
static const uint8_t * derive_scale_m(const VVCLocalContext *lc, const TransformBlock *tb, uint8_t *scale_m)
Definition: intra.c:351
is_cclm
static int is_cclm(enum IntraPredMode mode)
Definition: intra.c:34
ff_vvc_ctu_free_cus
void ff_vvc_ctu_free_cus(CodingUnit **cus)
Definition: ctu.c:2887