35 #define DEFAULT_INTRA_TC_OFFSET 2
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 3, 4, 4, 4, 4, 5, 5, 5, 5, 7, 7, 8, 9, 10,
41 10, 11, 13, 14, 15, 17, 19, 21, 24, 25, 29, 33, 36, 41, 45, 51,
42 57, 64, 71, 80, 89, 100, 112, 125, 141, 157, 177, 198, 222, 250, 280, 314,
48 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
49 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24,
50 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56,
51 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88,
58 const int min_tu_width =
fc->ps.pps->min_tu_width;
59 return fc->tab.qp[
chroma][x + y * min_tu_width];
63 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride)
65 for (
int y = 0; y <
height; y++) {
73 static void copy_pixel(uint8_t *dst,
const uint8_t *
src,
const int pixel_shift)
76 *(uint16_t *)dst = *(uint16_t *)
src;
82 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride)
85 if (pixel_shift == 0) {
93 *(uint16_t *)dst = *(uint16_t *)
src;
101 const ptrdiff_t src_stride,
const int x,
const int y,
const int width,
const int height,
102 const int c_idx,
const int rx,
const int ry,
const int top)
104 const int ps =
fc->ps.sps->pixel_shift;
105 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
106 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
110 memcpy(
fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry) *
w + x) << ps),
114 memcpy(
fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry + 1) *
w + x) << ps),
118 copy_vert(
fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * rx) *
h + y) << ps),
src, ps,
height, 1 << ps, src_stride);
119 copy_vert(
fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * rx + 1) *
h + y) << ps),
src + ((
width - 1) << ps), ps,
height, 1 << ps, src_stride);
126 const int ctb_size_y =
fc->ps.sps->ctb_size_y;
127 const int x0 = rx <<
fc->ps.sps->ctb_log2_size_y;
128 const int y0 = ry <<
fc->ps.sps->ctb_log2_size_y;
130 for (
int c_idx = 0; c_idx < (
fc->ps.sps->r->sps_chroma_format_idc ? 3 : 1); c_idx++) {
131 const int x = x0 >>
fc->ps.sps->hshift[c_idx];
132 const int y = y0 >>
fc->ps.sps->vshift[c_idx];
133 const ptrdiff_t src_stride =
fc->frame->linesize[c_idx];
134 const int ctb_size_h = ctb_size_y >>
fc->ps.sps->hshift[c_idx];
135 const int ctb_size_v = ctb_size_y >>
fc->ps.sps->vshift[c_idx];
136 const int width =
FFMIN(ctb_size_h, (
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx]) - x);
137 const int height =
FFMIN(ctb_size_v, (
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx]) - y);
138 const uint8_t *
src = &
fc->frame->data[c_idx][y * src_stride + (x <<
fc->ps.sps->pixel_shift)];
139 copy_ctb_to_hv(
fc,
src, src_stride, x, y,
width,
height, c_idx, rx, ry, top);
157 const int ctb_size_y =
fc->ps.sps->ctb_size_y;
158 static const uint8_t sao_tab[16] = { 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8 };
160 const int rx = x >>
fc->ps.sps->ctb_log2_size_y;
161 const int ry = y >>
fc->ps.sps->ctb_log2_size_y;
162 int edges[4] = { !rx, !ry, rx ==
fc->ps.pps->ctb_width - 1, ry ==
fc->ps.pps->ctb_height - 1 };
165 uint8_t vert_edge[] = { 0, 0 };
166 uint8_t horiz_edge[] = { 0, 0 };
167 uint8_t diag_edge[] = { 0, 0, 0, 0 };
168 uint8_t tile_edge[] = { 0, 0, 0, 0 };
169 uint8_t subpic_edge[] = { 0, 0, 0, 0 };
171 const uint8_t lfase =
fc->ps.pps->r->pps_loop_filter_across_slices_enabled_flag;
172 const uint8_t no_tile_filter =
fc->ps.pps->r->num_tiles_in_pic > 1 &&
173 !
fc->ps.pps->r->pps_loop_filter_across_tiles_enabled_flag;
174 const uint8_t no_subpic_filter =
fc->ps.sps->r->sps_num_subpics_minus1 &&
175 !
fc->ps.sps->r->sps_loop_filter_across_subpic_enabled_flag[subpic_idx];
176 const uint8_t restore = no_subpic_filter || no_tile_filter || !lfase;
180 tile_edge[
LEFT] = no_tile_filter &&
fc->ps.pps->ctb_to_col_bd[rx] == rx;
181 subpic_edge[
LEFT] = no_subpic_filter &&
fc->ps.sps->r->sps_subpic_ctu_top_left_x[subpic_idx] == rx;
182 vert_edge[0] = (!lfase &&
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx - 1, ry)) || tile_edge[
LEFT] || subpic_edge[
LEFT];
185 tile_edge[
RIGHT] = no_tile_filter &&
fc->ps.pps->ctb_to_col_bd[rx] !=
fc->ps.pps->ctb_to_col_bd[rx + 1];
186 subpic_edge[
RIGHT] = no_subpic_filter &&
187 fc->ps.sps->r->sps_subpic_ctu_top_left_x[subpic_idx] +
fc->ps.sps->r->sps_subpic_width_minus1[subpic_idx] == rx;
188 vert_edge[1] = (!lfase &&
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx + 1, ry)) || tile_edge[
RIGHT] || subpic_edge[
RIGHT];
191 tile_edge[
TOP] = no_tile_filter &&
fc->ps.pps->ctb_to_row_bd[ry] == ry;
192 subpic_edge[
TOP] = no_subpic_filter &&
fc->ps.sps->r->sps_subpic_ctu_top_left_y[subpic_idx] == ry;
193 horiz_edge[0] = (!lfase &&
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx, ry - 1)) || tile_edge[
TOP] || subpic_edge[
TOP];
196 tile_edge[
BOTTOM] = no_tile_filter &&
fc->ps.pps->ctb_to_row_bd[ry] !=
fc->ps.pps->ctb_to_row_bd[ry + 1];
197 subpic_edge[
BOTTOM] = no_subpic_filter &&
198 fc->ps.sps->r->sps_subpic_ctu_top_left_y[subpic_idx] +
fc->ps.sps->r->sps_subpic_height_minus1[subpic_idx] == ry;
199 horiz_edge[1] = (!lfase &&
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx, ry + 1)) || tile_edge[
BOTTOM] || subpic_edge[
BOTTOM];
201 if (!edges[
LEFT] && !edges[
TOP]) {
202 diag_edge[0] = (!lfase &&
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx - 1, ry - 1)) ||
203 tile_edge[
LEFT] || tile_edge[
TOP] || subpic_edge[
LEFT] || subpic_edge[
TOP];
206 diag_edge[1] = (!lfase &&
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx + 1, ry - 1)) ||
207 tile_edge[
RIGHT] || tile_edge[
TOP] || subpic_edge[
TOP] || subpic_edge[
RIGHT];
210 diag_edge[2] = (!lfase &&
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx + 1, ry + 1)) ||
214 diag_edge[3] = (!lfase &&
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx - 1, ry + 1)) ||
219 for (c_idx = 0; c_idx < (
fc->ps.sps->r->sps_chroma_format_idc ? 3 : 1); c_idx++) {
220 int x0 = x >>
fc->ps.sps->hshift[c_idx];
221 int y0 = y >>
fc->ps.sps->vshift[c_idx];
222 ptrdiff_t src_stride =
fc->frame->linesize[c_idx];
223 int ctb_size_h = ctb_size_y >>
fc->ps.sps->hshift[c_idx];
224 int ctb_size_v = ctb_size_y >>
fc->ps.sps->vshift[c_idx];
225 int width =
FFMIN(ctb_size_h, (
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx]) - x0);
226 int height =
FFMIN(ctb_size_v, (
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx]) - y0);
228 uint8_t *
src = &
fc->frame->data[c_idx][y0 * src_stride + (x0 <<
fc->ps.sps->pixel_shift)];
229 ptrdiff_t dst_stride;
234 fc->vvcdsp.sao.band_filter[
tab](
src,
src, src_stride, src_stride,
239 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
240 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
241 const int sh =
fc->ps.sps->pixel_shift;
248 const int right = 1 - edges[
RIGHT];
253 dst1 = dst - dst_stride - (
left << sh);
254 src1 =
fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry - 1) *
w + x0 -
left) << sh);
267 const int right = 1 - edges[
RIGHT];
272 dst1 = dst +
height * dst_stride - (
left << sh);
273 src1 =
fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry + 2) *
w + x0 -
left) << sh);
286 fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * rx - 1) *
h + y0) << sh),
287 sh,
height, dst_stride, 1 << sh);
291 fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * rx + 2) *
h + y0) << sh),
292 sh,
height, dst_stride, 1 << sh);
298 fc->vvcdsp.sao.edge_restore[restore](
src, dst, src_stride, dst_stride,
299 sao, edges,
width,
height, c_idx, vert_edge, horiz_edge, diag_edge);
306 #define TAB_BS(t, x, y) (t)[((y) >> 2) * (fc->tab.sz.bs_width) + ((x) >> 2)]
307 #define TAB_MAX_LEN(t, x, y) (t)[((y) >> 2) * (fc->tab.sz.bs_width) + ((x) >> 2)]
310 #define DEBLOCK_STEP 8
312 #define CHROMA_GRID 8
371 if (ref_A == ref_B) {
385 const int is_intra,
const int has_subblock,
const int vertical, uint8_t *max_len_p, uint8_t *max_len_q)
387 const int px = vertical ? qx - 1 : qx;
388 const int py = !vertical ? qy - 1 : qy;
389 const uint8_t *tb_size = vertical ?
fc->tab.tb_width[
LUMA] :
fc->tab.tb_height[
LUMA];
392 const int min_cb_log2 =
fc->ps.sps->min_cb_log2_size_y;
393 const int off_p = (py >> min_cb_log2) *
fc->ps.pps->min_cb_width + (px >> min_cb_log2);
394 if (size_p <= 4 || size_q <= 4) {
395 *max_len_p = *max_len_q = 1;
397 *max_len_p = *max_len_q = 3;
404 *max_len_q =
FFMIN(5, *max_len_q);
405 if (
fc->tab.msf[off_p] ||
fc->tab.iaf[off_p])
406 *max_len_p =
FFMIN(5, *max_len_p);
410 const int cb_x,
const int cb_y,
const int x0,
const int y0,
const int width,
const int height)
415 const int min_pu_width =
fc->ps.pps->min_pu_width;
419 for (
int j = 0; j <
height; j += 4) {
420 const int y_pu = (y0 + j) >> log2_min_pu_size;
422 for (
int i = 8 - ((x0 - cb_x) % 8);
i <
width;
i += 8) {
423 const int xp_pu = (x0 +
i - 1) >> log2_min_pu_size;
424 const int xq_pu = (x0 +
i) >> log2_min_pu_size;
425 const MvField *
left = &tab_mvf[y_pu * min_pu_width + xp_pu];
426 const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
427 const int x = x0 +
i;
428 const int y = y0 + j;
430 uint8_t max_len_p = 0, max_len_q = 0;
435 max_len_p = max_len_q = 1;
436 else if (
i == 8 ||
i ==
width - 8)
437 max_len_p = max_len_q = 2;
439 max_len_p = max_len_q = 3;
448 const int cb_x,
const int cb_y,
const int x0,
const int y0,
const int width,
const int height)
453 const int min_pu_width =
fc->ps.pps->min_pu_width;
457 for (
int j = 8 - ((y0 - cb_y) % 8); j <
height; j += 8) {
458 int yp_pu = (y0 + j - 1) >> log2_min_pu_size;
459 int yq_pu = (y0 + j) >> log2_min_pu_size;
461 for (
int i = 0;
i <
width;
i += 4) {
462 const int x_pu = (x0 +
i) >> log2_min_pu_size;
463 const MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
464 const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
465 const int x = x0 +
i;
466 const int y = y0 + j;
468 uint8_t max_len_p = 0, max_len_q = 0;
475 if (j == 4 || j ==
height - 4)
476 max_len_p = max_len_q = 1;
477 else if (j == 8 || j ==
height - 8)
478 max_len_p = max_len_q = 2;
480 max_len_p = max_len_q = 3;
488 const int x_p,
const int y_p,
const int x_q,
const int y_q,
489 const RefPicList *rpl_p,
const int c_idx,
const int off_to_cb,
const uint8_t has_sub_block)
495 const int log2_min_cb_size =
fc->ps.sps->min_cb_log2_size_y;
496 const int min_pu_width =
fc->ps.pps->min_pu_width;
497 const int min_tu_width =
fc->ps.pps->min_tu_width;
498 const int min_cb_width =
fc->ps.pps->min_cb_width;
499 const int pu_p = (y_p >> log2_min_pu_size) * min_pu_width + (x_p >> log2_min_pu_size);
500 const int pu_q = (y_q >> log2_min_pu_size) * min_pu_width + (x_q >> log2_min_pu_size);
501 const MvField *mvf_p = &tab_mvf[pu_p];
502 const MvField *mvf_q = &tab_mvf[pu_q];
503 const uint8_t
chroma = !!c_idx;
504 const int tu_p = (y_p >> log2_min_tu_size) * min_tu_width + (x_p >> log2_min_tu_size);
505 const int tu_q = (y_q >> log2_min_tu_size) * min_tu_width + (x_q >> log2_min_tu_size);
506 const uint8_t pcmf =
fc->tab.pcmf[
chroma][tu_p] &&
fc->tab.pcmf[
chroma][tu_q];
507 const int cb_p = (y_p >> log2_min_cb_size) * min_cb_width + (x_p >> log2_min_cb_size);
508 const int cb_q = (y_q >> log2_min_cb_size) * min_cb_width + (x_q >> log2_min_cb_size);
510 const uint8_t same_mode =
fc->tab.cpm[
chroma][cb_p] ==
fc->tab.cpm[
chroma][cb_q];
519 return fc->tab.tu_coded_flag[c_idx][tu_p] ||
520 fc->tab.tu_coded_flag[c_idx][tu_q] ||
521 fc->tab.tu_joint_cbcr_residual_flag[tu_p] ||
522 fc->tab.tu_joint_cbcr_residual_flag[tu_q];
525 if (
fc->tab.tu_coded_flag[
LUMA][tu_p] ||
fc->tab.tu_coded_flag[
LUMA][tu_q])
528 if ((off_to_cb && ((off_to_cb % 8) || !has_sub_block)))
538 const int pos,
const int rs,
const int vertical)
544 if (boundary && (
pos %
fc->ps.sps->ctb_size_y) == 0) {
557 const int q_rs = rs - (vertical ? 1 :
fc->ps.pps->ctb_width);
569 const int x0,
const int y0,
const int width,
const int height,
const int rs)
574 const int min_pu_width =
fc->ps.pps->min_pu_width;
575 const int min_cb_log2 =
fc->ps.sps->min_cb_log2_size_y;
576 const int min_cb_width =
fc->ps.pps->min_cb_width;
577 const int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
580 int has_vertical_sb = 0;
582 const int off_q = (y0 >> min_cb_log2) * min_cb_width + (x0 >> min_cb_log2);
583 const int cb_x =
fc->tab.cb_pos_x[
LUMA][off_q];
584 const int cb_y =
fc->tab.cb_pos_y[
LUMA][off_q];
585 const int cb_width =
fc->tab.cb_width[
LUMA][off_q];
586 const int off_x = cb_x - x0;
589 if (
fc->tab.msf[off_q] ||
fc->tab.iaf[off_q])
590 has_vertical_sb = cb_width > 8;
600 uint8_t max_len_p, max_len_q;
601 const int bs =
deblock_bs(lc, x0 - 1, y0 +
i, x0, y0 +
i, rpl_left, 0, off_x, has_vertical_sb);
612 if (
fc->tab.msf[off_q] ||
fc->tab.iaf[off_q])
618 const int x0,
const int y0,
const int width,
const int height,
const int rs)
623 const int min_pu_width =
fc->ps.pps->min_pu_width;
624 const int min_cb_log2 =
fc->ps.sps->min_cb_log2_size_y;
625 const int min_cb_width =
fc->ps.pps->min_cb_width;
626 const int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
629 int has_horizontal_sb = 0;
631 const int off_q = (y0 >> min_cb_log2) * min_cb_width + (x0 >> min_cb_log2);
632 const int cb_x =
fc->tab.cb_pos_x[
LUMA][off_q];
633 const int cb_y =
fc->tab.cb_pos_y[
LUMA][off_q];
634 const int cb_height =
fc->tab.cb_height[
LUMA][off_q];
635 const int off_y = y0 - cb_y;
638 if (
fc->tab.msf[off_q] ||
fc->tab.iaf[off_q])
639 has_horizontal_sb = cb_height > 8;
644 if (boundary_upper) {
648 for (
int i = 0;
i <
width;
i += 4) {
649 uint8_t max_len_p, max_len_q;
650 const int bs =
deblock_bs(lc, x0 +
i, y0 - 1, x0 +
i, y0, rpl_top, 0, off_y, has_horizontal_sb);
661 if (
fc->tab.msf[off_q] ||
fc->tab.iaf[off_q])
667 const int x0,
const int y0,
const int width,
const int height,
const int rs)
675 for (
int c_idx =
CB; c_idx <=
CR; c_idx++) {
676 const int bs =
deblock_bs(lc, x0 - 1, y0 +
i, x0, y0 +
i,
NULL, c_idx, 0, 0);
678 TAB_BS(
fc->tab.vertical_bs[c_idx], x0, (y0 +
i)) = bs;
685 const int x0,
const int y0,
const int width,
const int height,
const int rs)
691 if (boundary_upper) {
692 for (
int i = 0;
i <
width;
i += 2) {
693 for (
int c_idx =
CB; c_idx <=
CR; c_idx++) {
694 const int bs =
deblock_bs(lc, x0 +
i, y0 - 1, x0 +
i, y0,
NULL, c_idx, 0, 0);
696 TAB_BS(
fc->tab.horizontal_bs[c_idx], x0 +
i, y0) = bs;
710 const int ctb_size =
sps->ctb_size_y;
718 for (
int is_chroma = 0; is_chroma <= 1; is_chroma++) {
719 const int hs =
sps->hshift[is_chroma];
720 const int vs =
sps->vshift[is_chroma];
723 const int off = y *
fc->ps.pps->min_tu_width + x;
726 fc->tab.tb_width[is_chroma][off] << hs,
fc->tab.tb_height[is_chroma][off] << vs, rs);
735 const int vertical, uint8_t *max_len_p, uint8_t *max_len_q)
737 const uint8_t *tab_len_p = vertical ?
fc->tab.vertical_p :
fc->tab.horizontal_p;
738 const uint8_t *tab_len_q = vertical ?
fc->tab.vertical_q :
fc->tab.horizontal_q;
745 const int vertical,
const int horizontal_ctu_edge,
const int bs, uint8_t *max_len_p, uint8_t *max_len_q)
747 const int px = vertical ? qx - 1 : qx;
748 const int py = !vertical ? qy - 1 : qy;
749 const uint8_t *tb_size = vertical ?
fc->tab.tb_width[
CHROMA] :
fc->tab.tb_height[
CHROMA];
753 if (size_p >= 8 && size_q >= 8) {
754 *max_len_p = *max_len_q = 3;
755 if (horizontal_ctu_edge)
759 *max_len_p = *max_len_q = (bs == 2);
764 const int c_idx,
const int vertical,
const int horizontal_ctu_edge,
const int bs, uint8_t *max_len_p, uint8_t *max_len_q)
772 #define TC_CALC(qp, bs) \
773 tctable[av_clip((qp) + DEFAULT_INTRA_TC_OFFSET * ((bs) - 1) + \
775 0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)]
785 if (!
sps->r->sps_ladf_enabled_flag)
789 qp_offset =
sps->r->sps_ladf_lowest_interval_qp_offset;
790 for (
int i = 0;
i <
sps->num_ladf_intervals - 1 &&
level >
sps->ladf_interval_lower_bound[
i + 1];
i++)
791 qp_offset =
sps->r->sps_ladf_qp_offset[
i];
793 return qp + qp_offset;
800 return (
get_qPc(
fc, x - vertical, y - !vertical, c_idx) +
get_qPc(
fc, x, y, c_idx) - 2 *
sps->qp_bd_offset + 1) >> 1;
819 const uint8_t no_p[4] = { 0 };
820 const uint8_t no_q[4] = { 0 } ;
822 const int ctb_log2_size_y =
fc->ps.sps->ctb_log2_size_y;
824 const int ctb_size = 1 << ctb_log2_size_y;
825 const DBParams *params =
fc->tab.deblock + rs;
829 x_end = x0 + ctb_size;
830 if (x_end >
fc->ps.pps->width)
831 x_end =
fc->ps.pps->width;
832 y_end = y0 + ctb_size;
833 if (y_end >
fc->ps.pps->height)
834 y_end =
fc->ps.pps->height;
836 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
837 const int hs =
sps->hshift[c_idx];
838 const int vs =
sps->vshift[c_idx];
840 const int tc_offset = params->
tc_offset[c_idx];
841 const int beta_offset = params->
beta_offset[c_idx];
844 for (x = x0 ? x0 : grid; x < x_end; x += grid) {
845 int32_t bs[4], beta[4],
tc[4], all_zero_bs = 1;
846 uint8_t max_len_p[4], max_len_q[4];
848 for (
int i = 0; i < DEBLOCK_STEP >> (2 - vs);
i++) {
849 const int dy =
i << 2;
850 bs[
i] = (y + dy < y_end) ?
TAB_BS(
fc->tab.vertical_bs[c_idx], x, y + dy) : 0;
852 src = &
fc->frame->data[c_idx][((y + dy) >> vs) *
fc->frame->linesize[c_idx] + ((x >> hs) <<
fc->ps.sps->pixel_shift)];
864 src = &
fc->frame->data[c_idx][(y >> vs) *
fc->frame->linesize[c_idx] + ((x >> hs) <<
fc->ps.sps->pixel_shift)];
866 fc->vvcdsp.lf.filter_luma[1](
src,
fc->frame->linesize[c_idx],
867 beta,
tc, no_p, no_q, max_len_p, max_len_q, 0);
869 fc->vvcdsp.lf.filter_chroma[1](
src,
fc->frame->linesize[c_idx],
870 beta,
tc, no_p, no_q, max_len_p, max_len_q, vs);
887 const uint8_t no_p[4] = { 0 };
888 const uint8_t no_q[4] = { 0 } ;
890 const int ctb_log2_size_y =
fc->ps.sps->ctb_log2_size_y;
892 const int ctb_size = 1 << ctb_log2_size_y;
893 const DBParams *params =
fc->tab.deblock + rs;
897 x_end = x0 + ctb_size;
898 if (x_end >
fc->ps.pps->width)
899 x_end =
fc->ps.pps->width;
900 y_end = y0 + ctb_size;
901 if (y_end >
fc->ps.pps->height)
902 y_end =
fc->ps.pps->height;
904 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
905 const int hs =
sps->hshift[c_idx];
906 const int vs =
sps->vshift[c_idx];
908 const int beta_offset = params->
beta_offset[c_idx];
909 const int tc_offset = params->
tc_offset[c_idx];
911 for (y = y0; y < y_end; y += grid) {
912 const uint8_t horizontal_ctu_edge = !(y %
fc->ps.sps->ctb_size_y);
916 for (x = x0 ? x0: 0; x < x_end; x += (
DEBLOCK_STEP << hs)) {
917 int32_t bs[4], beta[4],
tc[4], all_zero_bs = 1;
918 uint8_t max_len_p[4], max_len_q[4];
920 for (
int i = 0; i < DEBLOCK_STEP >> (2 - hs);
i++) {
921 const int dx =
i << 2;
923 bs[
i] = (x + dx < x_end) ?
TAB_BS(
fc->tab.horizontal_bs[c_idx], x + dx, y) : 0;
925 src = &
fc->frame->data[c_idx][(y >> vs) *
fc->frame->linesize[c_idx] + (((x + dx)>> hs) <<
fc->ps.sps->pixel_shift)];
936 src = &
fc->frame->data[c_idx][(y >> vs) *
fc->frame->linesize[c_idx] + ((x >> hs) <<
fc->ps.sps->pixel_shift)];
938 fc->vvcdsp.lf.filter_luma[0](
src,
fc->frame->linesize[c_idx],
939 beta,
tc, no_p, no_q, max_len_p, max_len_q, horizontal_ctu_edge);
941 fc->vvcdsp.lf.filter_chroma[0](
src,
fc->frame->linesize[c_idx],
942 beta,
tc, no_p, no_q, max_len_p, max_len_q, hs);
951 const int pixel_shift,
int width,
const int height,
const ptrdiff_t dst_stride,
const ptrdiff_t src_stride)
953 width <<= pixel_shift;
964 if (pixel_shift == 0) {
966 memset(_dst, *_src,
width);
971 const uint16_t *
src = (
const uint16_t *)_src;
972 uint16_t *dst = (uint16_t *)_dst;
976 for (
int j = 0; j <
width; j++)
987 width <<= pixel_shift;
995 const int x,
const int y,
const int width,
const int height,
const int rx,
const int ry,
const int c_idx)
997 const int ps =
fc->ps.sps->pixel_shift;
998 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
999 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
1001 const int offset_h[] = { 0,
height - border_pixels };
1002 const int offset_v[] = { 0,
width - border_pixels };
1006 alf_copy_border(
fc->tab.alf_pixel_buffer_h[c_idx][
i] + ((border_pixels * ry *
w + x)<< ps),
1007 src + offset_h[
i] * src_stride, ps,
width, border_pixels,
w << ps, src_stride);
1011 alf_copy_border(
fc->tab.alf_pixel_buffer_v[c_idx][
i] + ((
h * rx + y) * (border_pixels << ps)),
1012 src + (offset_v[
i] << ps), ps, border_pixels,
height, border_pixels << ps, src_stride);
1016 static void alf_fill_border_h(uint8_t *dst,
const ptrdiff_t dst_stride,
const uint8_t *
src,
const ptrdiff_t src_stride,
1017 const uint8_t *border,
const int width,
const int border_pixels,
const int ps,
const int edge)
1026 const uint8_t *border,
const int border_pixels,
const int height,
const int pixel_shift,
const int *edges,
const int edge)
1028 const ptrdiff_t src_stride = (border_pixels << pixel_shift);
1037 pixel_shift, border_pixels,
height + (!edges[
TOP] + !edges[
BOTTOM]) * border_pixels, dst_stride, src_stride);
1041 alf_extend_horz(dst, dst + dst_stride * border_pixels, pixel_shift, border_pixels, border_pixels, dst_stride);
1045 dst += dst_stride * (border_pixels +
height);
1046 alf_extend_horz(dst, dst - dst_stride, pixel_shift, border_pixels, border_pixels, dst_stride);
1051 const int rx,
const int ry,
const int width,
const int height,
const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
1052 const int c_idx,
const int *edges)
1054 const int ps =
fc->ps.sps->pixel_shift;
1055 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
1056 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
1063 src =
fc->tab.alf_pixel_buffer_h[c_idx][1] + (((border_pixels *
w) << ps) * (ry - 1) + (x << ps));
1064 dst = _dst - border_pixels * dst_stride;
1068 src =
fc->tab.alf_pixel_buffer_h[c_idx][0] + (((border_pixels *
w) << ps) * (ry + 1) + (x << ps));
1069 dst = _dst +
height * dst_stride;
1074 src =
fc->tab.alf_pixel_buffer_v[c_idx][1] + (
h * (rx - 1) + y - border_pixels) * (border_pixels << ps);
1075 dst = _dst - (border_pixels << ps) - border_pixels * dst_stride;
1079 src =
fc->tab.alf_pixel_buffer_v[c_idx][0] + (
h * (rx + 1) + y - border_pixels) * (border_pixels << ps);
1080 dst = _dst + (
width << ps) - border_pixels * dst_stride;
1084 #define ALF_MAX_BLOCKS_IN_CTU (MAX_CTU_SIZE * MAX_CTU_SIZE / ALF_BLOCK_SIZE / ALF_BLOCK_SIZE)
1085 #define ALF_MAX_FILTER_SIZE (ALF_MAX_BLOCKS_IN_CTU * ALF_NUM_COEFF_LUMA)
1093 const int16_t *coeff_set;
1094 const uint8_t *clip_idx_set;
1095 const uint8_t *class_to_filt;
1102 clip_idx_set = &fixed_clip_set[0][0];
1107 coeff_set = &
aps->luma_coeff[0][0];
1108 clip_idx_set = &
aps->luma_clip_idx[0][0];
1111 fc->vvcdsp.alf.classify(class_idx, transpose_idx,
src, src_stride,
width,
height,
1113 fc->vvcdsp.alf.recon_coeff_and_clip(
coeff,
clip, class_idx, transpose_idx,
size,
1114 coeff_set, clip_idx_set, class_to_filt);
1118 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
const int x0,
const int y0,
1122 int vb_pos = _vb_pos - y0;
1123 int16_t *
coeff = (int16_t*)lc->
tmp;
1124 int16_t *
clip = (int16_t *)lc->
tmp1;
1136 const int offset[] = {0, 3, 5, 7};
1138 return 1 << (
sps->bit_depth -
offset[idx]);
1142 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
const int c_idx,
1149 const int16_t *
coeff =
aps->chroma_coeff[idx];
1159 const ptrdiff_t dst_stride,
const ptrdiff_t luma_stride,
const int c_idx,
1160 const int width,
const int height,
const int hs,
const int vs,
const int vb_pos,
ALFParams *alf)
1164 const int idx = c_idx - 1;
1171 fc->vvcdsp.alf.filter_cc(dst, dst_stride, luma, luma_stride,
width,
height, hs, vs,
coeff, vb_pos);
1178 const int rx = x0 >>
fc->ps.sps->ctb_log2_size_y;
1179 const int ry = y0 >>
fc->ps.sps->ctb_log2_size_y;
1180 const int ctb_size_y =
fc->ps.sps->ctb_size_y;
1181 const int ps =
fc->ps.sps->pixel_shift;
1184 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
1185 const int hs =
fc->ps.sps->hshift[c_idx];
1186 const int vs =
fc->ps.sps->vshift[c_idx];
1187 const int x = x0 >> hs;
1188 const int y = y0 >> vs;
1189 const int width =
FFMIN(
fc->ps.pps->width - x0, ctb_size_y) >> hs;
1190 const int height =
FFMIN(
fc->ps.pps->height - y0, ctb_size_y) >> vs;
1192 const int src_stride =
fc->frame->linesize[c_idx];
1193 uint8_t*
src = &
fc->frame->data[c_idx][y * src_stride + (x << ps)];
1204 const int rx = x0 >>
fc->ps.sps->ctb_log2_size_y;
1205 const int ry = y0 >>
fc->ps.sps->ctb_log2_size_y;
1206 const int ctb_size_y =
fc->ps.sps->ctb_size_y;
1207 const int ps =
fc->ps.sps->pixel_shift;
1213 int edges[
MAX_EDGES] = { rx == 0, ry == 0, rx ==
pps->ctb_width - 1, ry ==
pps->ctb_height - 1 };
1215 if (!
pps->r->pps_loop_filter_across_tiles_enabled_flag) {
1218 edges[
RIGHT] = edges[
RIGHT] ||
pps->ctb_to_col_bd[rx] !=
pps->ctb_to_col_bd[rx + 1];
1219 edges[
BOTTOM] = edges[
BOTTOM] ||
pps->ctb_to_row_bd[ry] !=
pps->ctb_to_row_bd[ry + 1];
1222 if (!
pps->r->pps_loop_filter_across_slices_enabled_flag) {
1225 edges[
RIGHT] = edges[
RIGHT] ||
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx + 1, ry);
1229 if (!
sps->r->sps_loop_filter_across_subpic_enabled_flag[subpic_idx]) {
1232 edges[
RIGHT] = edges[
RIGHT] ||
fc->ps.sps->r->sps_subpic_ctu_top_left_x[subpic_idx] +
fc->ps.sps->r->sps_subpic_width_minus1[subpic_idx] == rx;
1233 edges[
BOTTOM] = edges[
BOTTOM] ||
fc->ps.sps->r->sps_subpic_ctu_top_left_y[subpic_idx] +
fc->ps.sps->r->sps_subpic_height_minus1[subpic_idx] == ry;
1236 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
1237 const int hs =
fc->ps.sps->hshift[c_idx];
1238 const int vs =
fc->ps.sps->vshift[c_idx];
1239 const int ctb_size_h = ctb_size_y >> hs;
1240 const int ctb_size_v = ctb_size_y >> vs;
1241 const int x = x0 >> hs;
1242 const int y = y0 >> vs;
1243 const int pic_width =
fc->ps.pps->width >> hs;
1244 const int pic_height =
fc->ps.pps->height >> vs;
1245 const int width =
FFMIN(pic_width - x, ctb_size_h);
1246 const int height =
FFMIN(pic_height - y, ctb_size_v);
1247 const int src_stride =
fc->frame->linesize[c_idx];
1248 uint8_t *
src = &
fc->frame->data[c_idx][y * src_stride + (x << ps)];
1254 padded_stride, src_stride, c_idx, edges);
1280 const int ctb_size =
fc->ps.sps->ctb_size_y;
1281 const int width =
FFMIN(
fc->ps.pps->width - x, ctb_size);
1283 uint8_t *
data =
fc->frame->data[
LUMA] + y *
fc->frame->linesize[
LUMA] + (x <<
fc->ps.sps->pixel_shift);