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 x_ctb,
const int y_ctb,
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 * y_ctb) *
w + x) << ps),
114 memcpy(
fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 1) *
w + x) << ps),
118 copy_vert(
fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * x_ctb) *
h + y) << ps),
src, ps,
height, 1 << ps, src_stride);
119 copy_vert(
fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 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 };
161 const int x_ctb = x >>
fc->ps.sps->ctb_log2_size_y;
162 const int y_ctb = y >>
fc->ps.sps->ctb_log2_size_y;
165 uint8_t vert_edge[] = { 0, 0 };
166 uint8_t horiz_edge[] = { 0, 0 };
167 uint8_t diag_edge[] = { 0, 0, 0, 0 };
168 const uint8_t lfase =
fc->ps.pps->r->pps_loop_filter_across_slices_enabled_flag;
169 const uint8_t no_tile_filter =
fc->ps.pps->r->num_tiles_in_pic > 1 &&
170 !
fc->ps.pps->r->pps_loop_filter_across_tiles_enabled_flag;
171 const uint8_t restore = no_tile_filter || !lfase;
172 uint8_t left_tile_edge = 0;
173 uint8_t right_tile_edge = 0;
174 uint8_t up_tile_edge = 0;
175 uint8_t bottom_tile_edge = 0;
177 edges[
LEFT] = x_ctb == 0;
178 edges[
TOP] = y_ctb == 0;
179 edges[
RIGHT] = x_ctb ==
fc->ps.pps->ctb_width - 1;
180 edges[
BOTTOM] = y_ctb ==
fc->ps.pps->ctb_height - 1;
184 left_tile_edge = no_tile_filter &&
fc->ps.pps->ctb_to_col_bd[x_ctb] == x_ctb;
185 vert_edge[0] = (!lfase &&
CTB(
fc->tab.slice_idx, x_ctb, y_ctb) !=
CTB(
fc->tab.slice_idx, x_ctb - 1, y_ctb)) || left_tile_edge;
188 right_tile_edge = no_tile_filter &&
fc->ps.pps->ctb_to_col_bd[x_ctb] !=
fc->ps.pps->ctb_to_col_bd[x_ctb + 1];
189 vert_edge[1] = (!lfase &&
CTB(
fc->tab.slice_idx, x_ctb, y_ctb) !=
CTB(
fc->tab.slice_idx, x_ctb + 1, y_ctb)) || right_tile_edge;
192 up_tile_edge = no_tile_filter &&
fc->ps.pps->ctb_to_row_bd[y_ctb] == y_ctb;
193 horiz_edge[0] = (!lfase &&
CTB(
fc->tab.slice_idx, x_ctb, y_ctb) !=
CTB(
fc->tab.slice_idx, x_ctb, y_ctb - 1)) || up_tile_edge;
196 bottom_tile_edge = no_tile_filter &&
fc->ps.pps->ctb_to_row_bd[y_ctb] !=
fc->ps.pps->ctb_to_row_bd[y_ctb + 1];
197 horiz_edge[1] = (!lfase &&
CTB(
fc->tab.slice_idx, x_ctb, y_ctb) !=
CTB(
fc->tab.slice_idx, x_ctb, y_ctb + 1)) || bottom_tile_edge;
199 if (!edges[
LEFT] && !edges[
TOP]) {
200 diag_edge[0] = (!lfase &&
CTB(
fc->tab.slice_idx, x_ctb, y_ctb) !=
CTB(
fc->tab.slice_idx, x_ctb - 1, y_ctb - 1)) || left_tile_edge || up_tile_edge;
203 diag_edge[1] = (!lfase &&
CTB(
fc->tab.slice_idx, x_ctb, y_ctb) !=
CTB(
fc->tab.slice_idx, x_ctb + 1, y_ctb - 1)) || right_tile_edge || up_tile_edge;
206 diag_edge[2] = (!lfase &&
CTB(
fc->tab.slice_idx, x_ctb, y_ctb) !=
CTB(
fc->tab.slice_idx, x_ctb + 1, y_ctb + 1)) || right_tile_edge || bottom_tile_edge;
209 diag_edge[3] = (!lfase &&
CTB(
fc->tab.slice_idx, x_ctb, y_ctb) !=
CTB(
fc->tab.slice_idx, x_ctb - 1, y_ctb + 1)) || left_tile_edge || bottom_tile_edge;
213 for (c_idx = 0; c_idx < (
fc->ps.sps->r->sps_chroma_format_idc ? 3 : 1); c_idx++) {
214 int x0 = x >>
fc->ps.sps->hshift[c_idx];
215 int y0 = y >>
fc->ps.sps->vshift[c_idx];
216 ptrdiff_t src_stride =
fc->frame->linesize[c_idx];
217 int ctb_size_h = ctb_size_y >>
fc->ps.sps->hshift[c_idx];
218 int ctb_size_v = ctb_size_y >>
fc->ps.sps->vshift[c_idx];
219 int width =
FFMIN(ctb_size_h, (
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx]) - x0);
220 int height =
FFMIN(ctb_size_v, (
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx]) - y0);
222 uint8_t *
src = &
fc->frame->data[c_idx][y0 * src_stride + (x0 <<
fc->ps.sps->pixel_shift)];
223 ptrdiff_t dst_stride;
228 fc->vvcdsp.sao.band_filter[
tab](
src,
src, src_stride, src_stride,
233 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
234 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
235 const int sh =
fc->ps.sps->pixel_shift;
242 const int right = 1 - edges[
RIGHT];
247 dst1 = dst - dst_stride - (
left << sh);
248 src1 =
fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * y_ctb - 1) *
w + x0 -
left) << sh);
261 const int right = 1 - edges[
RIGHT];
266 dst1 = dst +
height * dst_stride - (
left << sh);
267 src1 =
fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * y_ctb + 2) *
w + x0 -
left) << sh);
280 fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * x_ctb - 1) *
h + y0) << sh),
281 sh,
height, dst_stride, 1 << sh);
285 fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * x_ctb + 2) *
h + y0) << sh),
286 sh,
height, dst_stride, 1 << sh);
292 fc->vvcdsp.sao.edge_restore[restore](
src, dst, src_stride, dst_stride,
293 sao, edges,
width,
height, c_idx, vert_edge, horiz_edge, diag_edge);
300 #define TAB_BS(t, x, y) (t)[((y) >> 2) * (fc->tab.sz.bs_width) + ((x) >> 2)]
301 #define TAB_MAX_LEN(t, x, y) (t)[((y) >> 2) * (fc->tab.sz.bs_width) + ((x) >> 2)]
304 #define DEBLOCK_STEP 8
306 #define CHROMA_GRID 8
365 if (ref_A == ref_B) {
379 const int is_intra,
const int has_subblock,
const int vertical, uint8_t *max_len_p, uint8_t *max_len_q)
381 const int px = vertical ? qx - 1 : qx;
382 const int py = !vertical ? qy - 1 : qy;
383 const uint8_t *tb_size = vertical ?
fc->tab.tb_width[
LUMA] :
fc->tab.tb_height[
LUMA];
386 const int min_cb_log2 =
fc->ps.sps->min_cb_log2_size_y;
387 const int off_p = (py >> min_cb_log2) *
fc->ps.pps->min_cb_width + (px >> min_cb_log2);
388 if (size_p <= 4 || size_q <= 4) {
389 *max_len_p = *max_len_q = 1;
391 *max_len_p = *max_len_q = 3;
398 *max_len_q =
FFMIN(5, *max_len_q);
399 if (
fc->tab.msf[off_p] ||
fc->tab.iaf[off_p])
400 *max_len_p =
FFMIN(5, *max_len_p);
404 const int cb_x,
const int cb_y,
const int x0,
const int y0,
const int width,
const int height)
409 const int min_pu_width =
fc->ps.pps->min_pu_width;
413 for (
int j = 0; j <
height; j += 4) {
414 const int y_pu = (y0 + j) >> log2_min_pu_size;
416 for (
int i = 8 - ((x0 - cb_x) % 8);
i <
width;
i += 8) {
417 const int xp_pu = (x0 +
i - 1) >> log2_min_pu_size;
418 const int xq_pu = (x0 +
i) >> log2_min_pu_size;
419 const MvField *
left = &tab_mvf[y_pu * min_pu_width + xp_pu];
420 const MvField *curr = &tab_mvf[y_pu * min_pu_width + xq_pu];
421 const int x = x0 +
i;
422 const int y = y0 + j;
424 uint8_t max_len_p = 0, max_len_q = 0;
429 max_len_p = max_len_q = 1;
430 else if (
i == 8 ||
i ==
width - 8)
431 max_len_p = max_len_q = 2;
433 max_len_p = max_len_q = 3;
442 const int cb_x,
const int cb_y,
const int x0,
const int y0,
const int width,
const int height)
447 const int min_pu_width =
fc->ps.pps->min_pu_width;
451 for (
int j = 8 - ((y0 - cb_y) % 8); j <
height; j += 8) {
452 int yp_pu = (y0 + j - 1) >> log2_min_pu_size;
453 int yq_pu = (y0 + j) >> log2_min_pu_size;
455 for (
int i = 0;
i <
width;
i += 4) {
456 const int x_pu = (x0 +
i) >> log2_min_pu_size;
457 const MvField *top = &tab_mvf[yp_pu * min_pu_width + x_pu];
458 const MvField *curr = &tab_mvf[yq_pu * min_pu_width + x_pu];
459 const int x = x0 +
i;
460 const int y = y0 + j;
462 uint8_t max_len_p = 0, max_len_q = 0;
469 if (j == 4 || j ==
height - 4)
470 max_len_p = max_len_q = 1;
471 else if (j == 8 || j ==
height - 8)
472 max_len_p = max_len_q = 2;
474 max_len_p = max_len_q = 3;
482 const int x_p,
const int y_p,
const int x_q,
const int y_q,
483 const RefPicList *rpl_p,
const int c_idx,
const int off_to_cb,
const uint8_t has_sub_block)
489 const int log2_min_cb_size =
fc->ps.sps->min_cb_log2_size_y;
490 const int min_pu_width =
fc->ps.pps->min_pu_width;
491 const int min_tu_width =
fc->ps.pps->min_tu_width;
492 const int min_cb_width =
fc->ps.pps->min_cb_width;
493 const int pu_p = (y_p >> log2_min_pu_size) * min_pu_width + (x_p >> log2_min_pu_size);
494 const int pu_q = (y_q >> log2_min_pu_size) * min_pu_width + (x_q >> log2_min_pu_size);
495 const MvField *mvf_p = &tab_mvf[pu_p];
496 const MvField *mvf_q = &tab_mvf[pu_q];
497 const uint8_t
chroma = !!c_idx;
498 const int tu_p = (y_p >> log2_min_tu_size) * min_tu_width + (x_p >> log2_min_tu_size);
499 const int tu_q = (y_q >> log2_min_tu_size) * min_tu_width + (x_q >> log2_min_tu_size);
500 const uint8_t pcmf =
fc->tab.pcmf[
chroma][tu_p] &&
fc->tab.pcmf[
chroma][tu_q];
501 const int cb_p = (y_p >> log2_min_cb_size) * min_cb_width + (x_p >> log2_min_cb_size);
502 const int cb_q = (y_q >> log2_min_cb_size) * min_cb_width + (x_q >> log2_min_cb_size);
504 const uint8_t same_mode =
fc->tab.cpm[
chroma][cb_p] ==
fc->tab.cpm[
chroma][cb_q];
513 return fc->tab.tu_coded_flag[c_idx][tu_p] ||
514 fc->tab.tu_coded_flag[c_idx][tu_q] ||
515 fc->tab.tu_joint_cbcr_residual_flag[tu_p] ||
516 fc->tab.tu_joint_cbcr_residual_flag[tu_q];
519 if (
fc->tab.tu_coded_flag[
LUMA][tu_p] ||
fc->tab.tu_coded_flag[
LUMA][tu_q])
522 if ((off_to_cb && ((off_to_cb % 8) || !has_sub_block)))
532 const int x0,
const int y0,
const int width,
const int height)
537 const int min_pu_width =
fc->ps.pps->min_pu_width;
538 const int min_cb_log2 =
fc->ps.sps->min_cb_log2_size_y;
539 const int min_cb_width =
fc->ps.pps->min_cb_width;
540 const int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
543 int has_vertical_sb = 0;
545 const int off_q = (y0 >> min_cb_log2) * min_cb_width + (x0 >> min_cb_log2);
546 const int cb_x =
fc->tab.cb_pos_x[
LUMA][off_q];
547 const int cb_y =
fc->tab.cb_pos_y[
LUMA][off_q];
548 const int cb_width =
fc->tab.cb_width[
LUMA][off_q];
549 const int off_x = cb_x - x0;
552 if (
fc->tab.msf[off_q] ||
fc->tab.iaf[off_q])
553 has_vertical_sb = cb_width > 8;
557 boundary_left = x0 > 0 && !(x0 & 3);
559 ((!
fc->ps.pps->r->pps_loop_filter_across_slices_enabled_flag &&
561 (x0 % (1 <<
fc->ps.sps->ctb_log2_size_y)) == 0) ||
562 (!
fc->ps.pps->r->pps_loop_filter_across_tiles_enabled_flag &&
564 (x0 % (1 <<
fc->ps.sps->ctb_log2_size_y)) == 0)))
571 uint8_t max_len_p, max_len_q;
572 const int bs =
deblock_bs(lc, x0 - 1, y0 +
i, x0, y0 +
i, rpl_left, 0, off_x, has_vertical_sb);
583 if (
fc->tab.msf[off_q] ||
fc->tab.iaf[off_q])
589 const int x0,
const int y0,
const int width,
const int height)
594 const int min_pu_width =
fc->ps.pps->min_pu_width;
595 const int min_cb_log2 =
fc->ps.sps->min_cb_log2_size_y;
596 const int min_cb_width =
fc->ps.pps->min_cb_width;
597 const int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
600 int has_horizontal_sb = 0;
602 const int off_q = (y0 >> min_cb_log2) * min_cb_width + (x0 >> min_cb_log2);
603 const int cb_x =
fc->tab.cb_pos_x[
LUMA][off_q];
604 const int cb_y =
fc->tab.cb_pos_y[
LUMA][off_q];
605 const int cb_height =
fc->tab.cb_height[
LUMA][off_q];
606 const int off_y = y0 - cb_y;
609 if (
fc->tab.msf[off_q] ||
fc->tab.iaf[off_q])
610 has_horizontal_sb = cb_height > 8;
613 boundary_upper = y0 > 0 && !(y0 & 3);
614 if (boundary_upper &&
615 ((!
fc->ps.pps->r->pps_loop_filter_across_slices_enabled_flag &&
617 (y0 % (1 <<
fc->ps.sps->ctb_log2_size_y)) == 0) ||
618 (!
fc->ps.pps->r->pps_loop_filter_across_tiles_enabled_flag &&
620 (y0 % (1 <<
fc->ps.sps->ctb_log2_size_y)) == 0)))
623 if (boundary_upper) {
627 for (
int i = 0;
i <
width;
i += 4) {
628 uint8_t max_len_p, max_len_q;
629 const int bs =
deblock_bs(lc, x0 +
i, y0 - 1, x0 +
i, y0, rpl_top, 0, off_y, has_horizontal_sb);
640 if (
fc->tab.msf[off_q] ||
fc->tab.iaf[off_q])
646 const int x0,
const int y0,
const int width,
const int height)
652 boundary_left = x0 > 0 && !(x0 & ((
CHROMA_GRID <<
fc->ps.sps->hshift[1]) - 1));
654 ((!
fc->ps.pps->r->pps_loop_filter_across_slices_enabled_flag &&
656 (x0 % (1 <<
fc->ps.sps->ctb_log2_size_y)) == 0) ||
657 (!
fc->ps.pps->r->pps_loop_filter_across_tiles_enabled_flag &&
659 (x0 % (1 <<
fc->ps.sps->ctb_log2_size_y)) == 0)))
664 for (
int c_idx =
CB; c_idx <=
CR; c_idx++) {
665 const int bs =
deblock_bs(lc, x0 - 1, y0 +
i, x0, y0 +
i,
NULL, c_idx, 0, 0);
667 TAB_BS(
fc->tab.vertical_bs[c_idx], x0, (y0 +
i)) = bs;
674 const int x0,
const int y0,
const int width,
const int height)
679 boundary_upper = y0 > 0 && !(y0 & ((
CHROMA_GRID <<
fc->ps.sps->vshift[1]) - 1));
680 if (boundary_upper &&
681 ((!
fc->ps.pps->r->pps_loop_filter_across_slices_enabled_flag &&
683 (y0 % (1 <<
fc->ps.sps->ctb_log2_size_y)) == 0) ||
684 (!
fc->ps.pps->r->pps_loop_filter_across_tiles_enabled_flag &&
686 (y0 % (1 <<
fc->ps.sps->ctb_log2_size_y)) == 0)))
689 if (boundary_upper) {
690 for (
int i = 0;
i <
width;
i += 2) {
691 for (
int c_idx =
CB; c_idx <=
CR; c_idx++) {
692 const int bs =
deblock_bs(lc, x0 +
i, y0 - 1, x0 +
i, y0,
NULL, c_idx, 0, 0);
694 TAB_BS(
fc->tab.horizontal_bs[c_idx], x0 +
i, y0) = bs;
708 const int ctb_size =
sps->ctb_size_y;
716 for (
int is_chroma = 0; is_chroma <= 1; is_chroma++) {
717 const int hs =
sps->hshift[is_chroma];
718 const int vs =
sps->vshift[is_chroma];
721 const int off = y *
fc->ps.pps->min_tu_width + x;
724 fc->tab.tb_width[is_chroma][off] << hs,
fc->tab.tb_height[is_chroma][off] << vs);
733 const int vertical, uint8_t *max_len_p, uint8_t *max_len_q)
735 const uint8_t *tab_len_p = vertical ?
fc->tab.vertical_p :
fc->tab.horizontal_p;
736 const uint8_t *tab_len_q = vertical ?
fc->tab.vertical_q :
fc->tab.horizontal_q;
743 const int vertical,
const int horizontal_ctu_edge,
const int bs, uint8_t *max_len_p, uint8_t *max_len_q)
745 const int px = vertical ? qx - 1 : qx;
746 const int py = !vertical ? qy - 1 : qy;
747 const uint8_t *tb_size = vertical ?
fc->tab.tb_width[
CHROMA] :
fc->tab.tb_height[
CHROMA];
751 if (size_p >= 8 && size_q >= 8) {
752 *max_len_p = *max_len_q = 3;
753 if (horizontal_ctu_edge)
757 *max_len_p = *max_len_q = (bs == 2);
762 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)
770 #define TC_CALC(qp, bs) \
771 tctable[av_clip((qp) + DEFAULT_INTRA_TC_OFFSET * ((bs) - 1) + \
773 0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)]
783 if (!
sps->r->sps_ladf_enabled_flag)
787 qp_offset =
sps->r->sps_ladf_lowest_interval_qp_offset;
788 for (
int i = 0;
i <
sps->num_ladf_intervals - 1 &&
level >
sps->ladf_interval_lower_bound[
i + 1];
i++)
789 qp_offset =
sps->r->sps_ladf_qp_offset[
i];
791 return qp + qp_offset;
798 return (
get_qPc(
fc, x - vertical, y - !vertical, c_idx) +
get_qPc(
fc, x, y, c_idx) - 2 *
sps->qp_bd_offset + 1) >> 1;
817 const uint8_t no_p[4] = { 0 };
818 const uint8_t no_q[4] = { 0 } ;
820 const int ctb_log2_size_y =
fc->ps.sps->ctb_log2_size_y;
822 const int ctb_size = 1 << ctb_log2_size_y;
823 const int ctb = (x0 >> ctb_log2_size_y) +
824 (y0 >> ctb_log2_size_y) *
fc->ps.pps->ctb_width;
825 const DBParams *params =
fc->tab.deblock + ctb;
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 int ctb = (x0 >> ctb_log2_size_y) +
894 (y0 >> ctb_log2_size_y) *
fc->ps.pps->ctb_width;
895 const DBParams *params =
fc->tab.deblock + ctb;
899 x_end = x0 + ctb_size;
900 if (x_end >
fc->ps.pps->width)
901 x_end =
fc->ps.pps->width;
902 y_end = y0 + ctb_size;
903 if (y_end >
fc->ps.pps->height)
904 y_end =
fc->ps.pps->height;
906 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
907 const int hs =
sps->hshift[c_idx];
908 const int vs =
sps->vshift[c_idx];
910 const int beta_offset = params->
beta_offset[c_idx];
911 const int tc_offset = params->
tc_offset[c_idx];
913 for (y = y0; y < y_end; y += grid) {
914 const uint8_t horizontal_ctu_edge = !(y %
fc->ps.sps->ctb_size_y);
918 for (x = x0 ? x0: 0; x < x_end; x += (
DEBLOCK_STEP << hs)) {
919 int32_t bs[4], beta[4],
tc[4], all_zero_bs = 1;
920 uint8_t max_len_p[4], max_len_q[4];
922 for (
int i = 0; i < DEBLOCK_STEP >> (2 - hs);
i++) {
923 const int dx =
i << 2;
925 bs[
i] = (x + dx < x_end) ?
TAB_BS(
fc->tab.horizontal_bs[c_idx], x + dx, y) : 0;
927 src = &
fc->frame->data[c_idx][(y >> vs) *
fc->frame->linesize[c_idx] + (((x + dx)>> hs) <<
fc->ps.sps->pixel_shift)];
938 src = &
fc->frame->data[c_idx][(y >> vs) *
fc->frame->linesize[c_idx] + ((x >> hs) <<
fc->ps.sps->pixel_shift)];
940 fc->vvcdsp.lf.filter_luma[0](
src,
fc->frame->linesize[c_idx],
941 beta,
tc, no_p, no_q, max_len_p, max_len_q, horizontal_ctu_edge);
943 fc->vvcdsp.lf.filter_chroma[0](
src,
fc->frame->linesize[c_idx],
944 beta,
tc, no_p, no_q, max_len_p, max_len_q, hs);
953 const int pixel_shift,
int width,
const int height,
const ptrdiff_t dst_stride,
const ptrdiff_t src_stride)
955 width <<= pixel_shift;
966 if (pixel_shift == 0) {
968 memset(_dst, *_src,
width);
973 const uint16_t *
src = (
const uint16_t *)_src;
974 uint16_t *dst = (uint16_t *)_dst;
978 for (
int j = 0; j <
width; j++)
989 width <<= pixel_shift;
997 const int x,
const int y,
const int width,
const int height,
const int x_ctb,
const int y_ctb,
const int c_idx)
999 const int ps =
fc->ps.sps->pixel_shift;
1000 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
1001 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
1003 const int offset_h[] = { 0,
height - border_pixels };
1004 const int offset_v[] = { 0,
width - border_pixels };
1008 alf_copy_border(
fc->tab.alf_pixel_buffer_h[c_idx][
i] + ((border_pixels * y_ctb *
w + x)<< ps),
1009 src + offset_h[
i] * src_stride, ps,
width, border_pixels,
w << ps, src_stride);
1013 alf_copy_border(
fc->tab.alf_pixel_buffer_v[c_idx][
i] + ((
h * x_ctb + y) * (border_pixels << ps)),
1014 src + (offset_v[
i] << ps), ps, border_pixels,
height, border_pixels << ps, src_stride);
1018 static void alf_fill_border_h(uint8_t *dst,
const ptrdiff_t dst_stride,
const uint8_t *
src,
const ptrdiff_t src_stride,
1019 const uint8_t *border,
const int width,
const int border_pixels,
const int ps,
const int edge)
1028 const uint8_t *border,
const int border_pixels,
const int height,
const int pixel_shift,
const int *edges,
const int edge)
1030 const ptrdiff_t src_stride = (border_pixels << pixel_shift);
1039 pixel_shift, border_pixels,
height + (!edges[
TOP] + !edges[
BOTTOM]) * border_pixels, dst_stride, src_stride);
1043 alf_extend_horz(dst, dst + dst_stride * border_pixels, pixel_shift, border_pixels, border_pixels, dst_stride);
1047 dst += dst_stride * (border_pixels +
height);
1048 alf_extend_horz(dst, dst - dst_stride, pixel_shift, border_pixels, border_pixels, dst_stride);
1053 const int x_ctb,
const int y_ctb,
const int width,
const int height,
const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
1054 const int c_idx,
const int *edges)
1056 const int ps =
fc->ps.sps->pixel_shift;
1057 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
1058 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
1065 src =
fc->tab.alf_pixel_buffer_h[c_idx][1] + (((border_pixels *
w) << ps) * (y_ctb - 1) + (x << ps));
1066 dst = _dst - border_pixels * dst_stride;
1070 src =
fc->tab.alf_pixel_buffer_h[c_idx][0] + (((border_pixels *
w) << ps) * (y_ctb + 1) + (x << ps));
1071 dst = _dst +
height * dst_stride;
1076 src =
fc->tab.alf_pixel_buffer_v[c_idx][1] + (
h * (x_ctb - 1) + y - border_pixels) * (border_pixels << ps);
1077 dst = _dst - (border_pixels << ps) - border_pixels * dst_stride;
1081 src =
fc->tab.alf_pixel_buffer_v[c_idx][0] + (
h * (x_ctb + 1) + y - border_pixels) * (border_pixels << ps);
1082 dst = _dst + (
width << ps) - border_pixels * dst_stride;
1086 #define ALF_MAX_BLOCKS_IN_CTU (MAX_CTU_SIZE * MAX_CTU_SIZE / ALF_BLOCK_SIZE / ALF_BLOCK_SIZE)
1087 #define ALF_MAX_FILTER_SIZE (ALF_MAX_BLOCKS_IN_CTU * ALF_NUM_COEFF_LUMA)
1095 const int16_t *coeff_set;
1096 const uint8_t *clip_idx_set;
1097 const uint8_t *class_to_filt;
1104 clip_idx_set = &fixed_clip_set[0][0];
1109 coeff_set = &
aps->luma_coeff[0][0];
1110 clip_idx_set = &
aps->luma_clip_idx[0][0];
1113 fc->vvcdsp.alf.classify(class_idx, transpose_idx,
src, src_stride,
width,
height,
1115 fc->vvcdsp.alf.recon_coeff_and_clip(
coeff,
clip, class_idx, transpose_idx,
size,
1116 coeff_set, clip_idx_set, class_to_filt);
1120 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
const int x0,
const int y0,
1124 int vb_pos = _vb_pos - y0;
1125 int16_t *
coeff = (int16_t*)lc->
tmp;
1126 int16_t *
clip = (int16_t *)lc->
tmp1;
1138 const int offset[] = {0, 3, 5, 7};
1140 return 1 << (
sps->bit_depth -
offset[idx]);
1144 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
const int c_idx,
1151 const int16_t *
coeff =
aps->chroma_coeff[idx];
1161 const ptrdiff_t dst_stride,
const ptrdiff_t luma_stride,
const int c_idx,
1162 const int width,
const int height,
const int hs,
const int vs,
const int vb_pos,
ALFParams *alf)
1166 const int idx = c_idx - 1;
1173 fc->vvcdsp.alf.filter_cc(dst, dst_stride, luma, luma_stride,
width,
height, hs, vs,
coeff, vb_pos);
1180 const int x_ctb = x0 >>
fc->ps.sps->ctb_log2_size_y;
1181 const int y_ctb = y0 >>
fc->ps.sps->ctb_log2_size_y;
1182 const int ctb_size_y =
fc->ps.sps->ctb_size_y;
1183 const int ps =
fc->ps.sps->pixel_shift;
1186 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
1187 const int hs =
fc->ps.sps->hshift[c_idx];
1188 const int vs =
fc->ps.sps->vshift[c_idx];
1189 const int x = x0 >> hs;
1190 const int y = y0 >> vs;
1191 const int width =
FFMIN(
fc->ps.pps->width - x0, ctb_size_y) >> hs;
1192 const int height =
FFMIN(
fc->ps.pps->height - y0, ctb_size_y) >> vs;
1194 const int src_stride =
fc->frame->linesize[c_idx];
1195 uint8_t*
src = &
fc->frame->data[c_idx][y * src_stride + (x << ps)];
1205 const int x_ctb = x0 >>
fc->ps.sps->ctb_log2_size_y;
1206 const int y_ctb = y0 >>
fc->ps.sps->ctb_log2_size_y;
1207 const int ctb_size_y =
fc->ps.sps->ctb_size_y;
1208 const int ps =
fc->ps.sps->pixel_shift;
1213 int edges[
MAX_EDGES] = { x_ctb == 0, y_ctb == 0, x_ctb ==
pps->ctb_width - 1, y_ctb ==
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[x_ctb] !=
pps->ctb_to_col_bd[x_ctb + 1];
1219 edges[
BOTTOM] = edges[
BOTTOM] ||
pps->ctb_to_row_bd[y_ctb] !=
pps->ctb_to_row_bd[y_ctb + 1];
1222 if (!
pps->r->pps_loop_filter_across_slices_enabled_flag) {
1225 edges[
RIGHT] = edges[
RIGHT] ||
CTB(
fc->tab.slice_idx, x_ctb, y_ctb) !=
CTB(
fc->tab.slice_idx, x_ctb + 1, y_ctb);
1226 edges[
BOTTOM] = edges[
BOTTOM] ||
CTB(
fc->tab.slice_idx, x_ctb, y_ctb) !=
CTB(
fc->tab.slice_idx, x_ctb, y_ctb + 1);
1229 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
1230 const int hs =
fc->ps.sps->hshift[c_idx];
1231 const int vs =
fc->ps.sps->vshift[c_idx];
1232 const int ctb_size_h = ctb_size_y >> hs;
1233 const int ctb_size_v = ctb_size_y >> vs;
1234 const int x = x0 >> hs;
1235 const int y = y0 >> vs;
1236 const int pic_width =
fc->ps.pps->width >> hs;
1237 const int pic_height =
fc->ps.pps->height >> vs;
1238 const int width =
FFMIN(pic_width - x, ctb_size_h);
1239 const int height =
FFMIN(pic_height - y, ctb_size_v);
1240 const int src_stride =
fc->frame->linesize[c_idx];
1241 uint8_t *
src = &
fc->frame->data[c_idx][y * src_stride + (x << ps)];
1247 padded_stride, src_stride, c_idx, edges);
1273 const int ctb_size =
fc->ps.sps->ctb_size_y;
1274 const int width =
FFMIN(
fc->ps.pps->width - x, ctb_size);
1276 uint8_t *
data =
fc->frame->data[
LUMA] + y *
fc->frame->linesize[
LUMA] + (x <<
fc->ps.sps->pixel_shift);