36 #define DEFAULT_INTRA_TC_OFFSET 2
38 #define POS(c_idx, x, y) \
39 &fc->frame->data[c_idx][((y) >> fc->ps.sps->vshift[c_idx]) * fc->frame->linesize[c_idx] + \
40 (((x) >> fc->ps.sps->hshift[c_idx]) << fc->ps.sps->pixel_shift)]
44 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 0, 0, 3, 4, 4, 4, 4, 5, 5, 5, 5, 7, 7, 8, 9, 10,
46 10, 11, 13, 14, 15, 17, 19, 21, 24, 25, 29, 33, 36, 41, 45, 51,
47 57, 64, 71, 80, 89, 100, 112, 125, 141, 157, 177, 198, 222, 250, 280, 314,
53 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
54 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24,
55 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56,
56 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88,
66 const uint16_t *vbs = vertical ?
ph->vb_pos_x :
ph->vb_pos_y;
67 const uint8_t nb_vbs = vertical ?
ph->num_ver_vbs :
ph->num_hor_vbs;
68 const int pos = ctu_pos <<
sps->ctb_log2_size_y;
70 if (
sps->r->sps_virtual_boundaries_enabled_flag) {
71 for (
int i = 0;
i < nb_vbs;
i++) {
72 const int o = vbs[
i] -
pos;
73 if (o >= 0 && o < sps->ctb_size_y)
89 const int min_tu_width =
fc->ps.pps->min_tu_width;
90 return fc->tab.qp[
chroma][x + y * min_tu_width];
94 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride)
96 for (
int y = 0; y <
height; y++) {
104 static void copy_pixel(uint8_t *dst,
const uint8_t *
src,
const int pixel_shift)
107 *(uint16_t *)dst = *(uint16_t *)
src;
113 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride)
116 if (pixel_shift == 0) {
124 *(uint16_t *)dst = *(uint16_t *)
src;
132 const ptrdiff_t src_stride,
const int x,
const int y,
const int width,
const int height,
133 const int c_idx,
const int rx,
const int ry,
const int top)
135 const int ps =
fc->ps.sps->pixel_shift;
136 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
137 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
141 memcpy(
fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry) *
w + x) << ps),
145 memcpy(
fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry + 1) *
w + x) << ps),
149 copy_vert(
fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * rx) *
h + y) << ps),
src, ps,
height, 1 << ps, src_stride);
150 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);
157 const int ctb_size_y =
fc->ps.sps->ctb_size_y;
158 const int x0 = rx <<
fc->ps.sps->ctb_log2_size_y;
159 const int y0 = ry <<
fc->ps.sps->ctb_log2_size_y;
161 for (
int c_idx = 0; c_idx < (
fc->ps.sps->r->sps_chroma_format_idc ? 3 : 1); c_idx++) {
162 const int x = x0 >>
fc->ps.sps->hshift[c_idx];
163 const int y = y0 >>
fc->ps.sps->vshift[c_idx];
164 const ptrdiff_t src_stride =
fc->frame->linesize[c_idx];
165 const int ctb_size_h = ctb_size_y >>
fc->ps.sps->hshift[c_idx];
166 const int ctb_size_v = ctb_size_y >>
fc->ps.sps->vshift[c_idx];
167 const int width =
FFMIN(ctb_size_h, (
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx]) - x);
168 const int height =
FFMIN(ctb_size_v, (
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx]) - y);
169 const uint8_t *
src =
POS(c_idx, x0, y0);
170 copy_ctb_to_hv(
fc,
src, src_stride, x, y,
width,
height, c_idx, rx, ry, top);
187 const uint8_t lfase =
fc->ps.pps->r->pps_loop_filter_across_slices_enabled_flag;
189 return lfase ||
CTB(
fc->tab.slice_idx, rx, ry) ==
CTB(
fc->tab.slice_idx, rx + dx, ry + dy);
192 static void sao_get_edges(uint8_t vert_edge[2], uint8_t horiz_edge[2], uint8_t diag_edge[4],
int *restore,
193 const VVCLocalContext *lc,
const int edges[4],
const int rx,
const int ry)
200 const uint8_t lfase =
fc->ps.pps->r->pps_loop_filter_across_slices_enabled_flag;
201 const uint8_t no_tile_filter =
pps->r->num_tiles_in_pic > 1 && !
pps->r->pps_loop_filter_across_tiles_enabled_flag;
203 uint8_t lf_edge[] = { 0, 0, 0, 0 };
211 lf_edge[
LEFT] = no_tile_filter &&
pps->ctb_to_col_bd[rx] == rx;
217 lf_edge[
RIGHT] = no_tile_filter &&
pps->ctb_to_col_bd[rx] !=
pps->ctb_to_col_bd[rx + 1];
223 lf_edge[
TOP] = no_tile_filter &&
pps->ctb_to_row_bd[ry] == ry;
229 lf_edge[
BOTTOM] = no_tile_filter &&
pps->ctb_to_row_bd[ry] !=
pps->ctb_to_row_bd[ry + 1];
235 if (!edges[
LEFT] && !edges[
TOP])
249 const uint8_t *
src,
const ptrdiff_t src_stride,
const int width,
const int edges[4],
const int ps)
252 const int right = 1 - edges[
RIGHT];
270 const uint8_t *
src,
const ptrdiff_t src_stride,
const int width,
const int height,
271 const VVCFrameContext *
fc,
const int x0,
const int y0,
const int rx,
const int ry,
const int edges[4],
const int c_idx)
273 const uint8_t *sao_h =
fc->tab.sao_pixel_buffer_h[c_idx];
274 const uint8_t *sao_v =
fc->tab.sao_pixel_buffer_v[c_idx];
275 const int x = x0 >>
fc->ps.sps->hshift[c_idx];
276 const int y = y0 >>
fc->ps.sps->vshift[c_idx];
277 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
278 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
279 const int ps =
fc->ps.sps->pixel_shift;
282 sao_copy_hor(dst - dst_stride, dst_stride, sao_h + (((2 * ry - 1) *
w + x) << ps), src_stride,
width, edges, ps);
285 sao_copy_hor(dst +
height * dst_stride, dst_stride, sao_h + (((2 * ry + 2) *
w + x) << ps), src_stride,
width, edges, ps);
288 copy_vert(dst - (1 << ps), sao_v + (((2 * rx - 1) *
h + y) << ps), ps,
height, dst_stride, 1 << ps);
291 copy_vert(dst + (
width << ps), sao_v + (((2 * rx + 2) *
h + y) << ps), ps,
height, dst_stride, 1 << ps);
296 static void sao_restore_vb(uint8_t *dst, ptrdiff_t dst_stride,
const uint8_t *
src, ptrdiff_t src_stride,
297 const int width,
const int height,
const int vb_pos,
const int ps,
const int vertical)
308 dst += dy * dst_stride +(dx << ps);
309 src += dy * src_stride +(dx << ps);
318 const int rx = x0 >>
sps->ctb_log2_size_y;
319 const int ry = y0 >>
sps->ctb_log2_size_y;
320 const int edges[4] = { !rx, !ry, rx ==
fc->ps.pps->ctb_width - 1, ry ==
fc->ps.pps->ctb_height - 1 };
323 uint8_t vert_edge[] = { 0, 0 };
324 uint8_t horiz_edge[] = { 0, 0 };
325 uint8_t diag_edge[] = { 0, 0, 0, 0 };
326 int restore, vb_x = 0, vb_y = 0;;
328 if (
sps->r->sps_virtual_boundaries_enabled_flag) {
333 sao_get_edges(vert_edge, horiz_edge, diag_edge, &restore, lc, edges, rx, ry);
335 for (
int c_idx = 0; c_idx < (
sps->r->sps_chroma_format_idc ? 3 : 1); c_idx++) {
336 static const uint8_t sao_tab[16] = { 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8 };
337 const ptrdiff_t src_stride =
fc->frame->linesize[c_idx];
338 uint8_t *
src =
POS(c_idx, x0, y0);
339 const int hs =
sps->hshift[c_idx];
340 const int vs =
sps->vshift[c_idx];
341 const int ps =
sps->pixel_shift;
342 const int width =
FFMIN(
sps->ctb_size_y,
fc->ps.pps->width - x0) >> hs;
345 const int sao_eo_class = sao->
eo_class[c_idx];
349 fc->vvcdsp.sao.band_filter[
tab](
src,
src, src_stride, src_stride,
357 sao_extends_edges(dst, dst_stride,
src, src_stride,
width,
height,
fc, x0, y0, rx, ry, edges, c_idx);
361 fc->vvcdsp.sao.edge_restore[restore](
src, dst, src_stride, dst_stride,
362 sao, edges,
width,
height, c_idx, vert_edge, horiz_edge, diag_edge);
375 #define TAB_BS(t, x, y) (t)[((y) >> 2) * (fc->tab.sz.bs_width) + ((x) >> 2)]
376 #define TAB_MAX_LEN(t, x, y) (t)[((y) >> 2) * (fc->tab.sz.bs_width) + ((x) >> 2)]
379 #define DEBLOCK_STEP 8
381 #define CHROMA_GRID 8
440 if (ref_A == ref_B) {
454 const int is_intra,
const int has_subblock,
const int vertical, uint8_t *max_len_p, uint8_t *max_len_q)
456 const int px = vertical ? qx - 1 : qx;
457 const int py = !vertical ? qy - 1 : qy;
458 const uint8_t *tb_size = vertical ?
fc->tab.tb_width[
LUMA] :
fc->tab.tb_height[
LUMA];
461 const int min_cb_log2 =
fc->ps.sps->min_cb_log2_size_y;
462 const int off_p = (py >> min_cb_log2) *
fc->ps.pps->min_cb_width + (px >> min_cb_log2);
463 if (size_p <= 4 || size_q <= 4) {
464 *max_len_p = *max_len_q = 1;
466 *max_len_p = *max_len_q = 3;
473 *max_len_q =
FFMIN(5, *max_len_q);
474 if (
fc->tab.msf[off_p] ||
fc->tab.iaf[off_p])
475 *max_len_p =
FFMIN(5, *max_len_p);
479 const int cb,
int x0,
int y0,
int width,
int height,
const int vertical)
484 int stridea =
fc->ps.pps->min_pu_width;
491 FFSWAP(
int, stridea, strideb);
495 for (
int i = 8 - ((x0 -
cb) % 8);
i <
width;
i += 8) {
497 const int xp_pu = (x0 +
i - 1) >> log2_min_pu_size;
498 const int xq_pu = (x0 +
i) >> log2_min_pu_size;
500 for (
int j = 0; j <
height; j += 4) {
501 const int y_pu = (y0 + j) >> log2_min_pu_size;
502 const MvField *mvf_p = &tab_mvf[y_pu * stridea + xp_pu * strideb];
503 const MvField *mvf_q = &tab_mvf[y_pu * stridea + xq_pu * strideb];
507 uint8_t max_len_p = 0, max_len_q = 0;
515 max_len_p = max_len_q = 1;
516 else if (
i == 8 ||
i ==
width - 8)
517 max_len_p = max_len_q = 2;
519 max_len_p = max_len_q = 3;
528 const int x_p,
const int y_p,
const int x_q,
const int y_q,
529 const RefPicList *rpl_p,
const int c_idx,
const int off_to_cb,
const uint8_t has_sub_block)
535 const int log2_min_cb_size =
fc->ps.sps->min_cb_log2_size_y;
536 const int min_pu_width =
fc->ps.pps->min_pu_width;
537 const int min_tu_width =
fc->ps.pps->min_tu_width;
538 const int min_cb_width =
fc->ps.pps->min_cb_width;
539 const int pu_p = (y_p >> log2_min_pu_size) * min_pu_width + (x_p >> log2_min_pu_size);
540 const int pu_q = (y_q >> log2_min_pu_size) * min_pu_width + (x_q >> log2_min_pu_size);
541 const MvField *mvf_p = &tab_mvf[pu_p];
542 const MvField *mvf_q = &tab_mvf[pu_q];
543 const uint8_t
chroma = !!c_idx;
544 const int tu_p = (y_p >> log2_min_tu_size) * min_tu_width + (x_p >> log2_min_tu_size);
545 const int tu_q = (y_q >> log2_min_tu_size) * min_tu_width + (x_q >> log2_min_tu_size);
546 const uint8_t pcmf =
fc->tab.pcmf[
chroma][tu_p] &&
fc->tab.pcmf[
chroma][tu_q];
547 const int cb_p = (y_p >> log2_min_cb_size) * min_cb_width + (x_p >> log2_min_cb_size);
548 const int cb_q = (y_q >> log2_min_cb_size) * min_cb_width + (x_q >> log2_min_cb_size);
550 const uint8_t same_mode =
fc->tab.cpm[
chroma][cb_p] ==
fc->tab.cpm[
chroma][cb_q];
559 return fc->tab.tu_coded_flag[c_idx][tu_p] ||
560 fc->tab.tu_coded_flag[c_idx][tu_q] ||
561 fc->tab.tu_joint_cbcr_residual_flag[tu_p] ||
562 fc->tab.tu_joint_cbcr_residual_flag[tu_q];
565 if (
fc->tab.tu_coded_flag[
LUMA][tu_p] ||
fc->tab.tu_coded_flag[
LUMA][tu_q])
568 if ((off_to_cb && ((off_to_cb % 8) || !has_sub_block)))
578 const int pos,
const int rs,
const int vertical)
584 if (boundary && (
pos %
fc->ps.sps->ctb_size_y) == 0) {
597 const int q_rs = rs - (vertical ? 1 :
fc->ps.pps->ctb_width);
609 const int x0,
const int y0,
const int width,
const int height,
const int rs,
const int vertical)
615 const int min_pu_width =
fc->ps.pps->min_pu_width;
616 const int min_cb_log2 =
fc->ps.sps->min_cb_log2_size_y;
617 const int min_cb_width =
fc->ps.pps->min_cb_width;
618 const int pos = vertical ? x0 : y0;
619 const int off_q = (y0 >> min_cb_log2) * min_cb_width + (x0 >> min_cb_log2);
620 const int cb = (vertical ?
fc->tab.cb_pos_x :
fc->tab.cb_pos_y )[
LUMA][off_q];
621 const int is_intra = tab_mvf[(y0 >> log2_min_pu_size) * min_pu_width +
627 const int off =
cb -
pos;
628 const int cb_size = (vertical ?
fc->tab.cb_width :
fc->tab.cb_height)[
LUMA][off_q];
629 const int has_sb = !is_intra && (
fc->tab.msf[off_q] ||
fc->tab.iaf[off_q]) && cb_size > 8;
634 for (
int i = 0;
i <
size;
i += 4) {
635 const int x = x0 +
i * !vertical;
636 const int y = y0 +
i * vertical;
637 uint8_t max_len_p, max_len_q;
638 const int bs = is_vb ? 0 :
deblock_bs(lc, x - vertical, y - !vertical, x, y, rpl_p,
LUMA, off, has_sb);
649 if (
fc->tab.msf[off_q] ||
fc->tab.iaf[off_q])
655 const int x0,
const int y0,
const int width,
const int height,
const int rs,
const int vertical)
658 const int shift = (vertical ?
fc->ps.sps->hshift :
fc->ps.sps->vshift)[
CHROMA];
660 const int pos = vertical ? x0 : y0;
666 for (
int c_idx =
CB; c_idx <=
CR; c_idx++) {
667 for (
int i = 0;
i <
size;
i += 2) {
668 const int x = x0 +
i * !vertical;
669 const int y = y0 +
i * vertical;
670 const int bs = is_vb ? 0 :
deblock_bs(lc, x - vertical, y - !vertical, x, y,
NULL, c_idx, 0, 0);
672 TAB_BS(
fc->tab.bs[vertical][c_idx], x, y) = bs;
679 const int width,
const int height,
const int rs,
const int vertical);
686 const int ctb_size =
sps->ctb_size_y;
693 for (
int is_chroma = 0; is_chroma <= 1; is_chroma++) {
694 const int hs =
sps->hshift[is_chroma];
695 const int vs =
sps->vshift[is_chroma];
698 const int off = y *
fc->ps.pps->min_tu_width + x;
701 fc->tab.tb_width[is_chroma][off] << hs,
fc->tab.tb_height[is_chroma][off] << vs, rs, vertical);
710 const int vertical, uint8_t *max_len_p, uint8_t *max_len_q)
712 *max_len_p =
TAB_MAX_LEN(
fc->tab.max_len_p[vertical], qx, qy);
713 *max_len_q =
TAB_MAX_LEN(
fc->tab.max_len_q[vertical], qx, qy);
718 const int vertical,
const int horizontal_ctu_edge,
const int bs, uint8_t *max_len_p, uint8_t *max_len_q)
720 const int px = vertical ? qx - 1 : qx;
721 const int py = !vertical ? qy - 1 : qy;
722 const uint8_t *tb_size = vertical ?
fc->tab.tb_width[
CHROMA] :
fc->tab.tb_height[
CHROMA];
726 if (size_p >= 8 && size_q >= 8) {
727 *max_len_p = *max_len_q = 3;
728 if (horizontal_ctu_edge)
732 *max_len_p = *max_len_q = (bs == 2);
737 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)
745 #define TC_CALC(qp, bs) \
746 tctable[av_clip((qp) + DEFAULT_INTRA_TC_OFFSET * ((bs) - 1) + \
748 0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)]
758 if (!
sps->r->sps_ladf_enabled_flag)
762 qp_offset =
sps->r->sps_ladf_lowest_interval_qp_offset;
763 for (
int i = 0;
i <
sps->num_ladf_intervals - 1 &&
level >
sps->ladf_interval_lower_bound[
i + 1];
i++)
764 qp_offset =
sps->r->sps_ladf_qp_offset[
i];
766 return qp + qp_offset;
773 return (
get_qPc(
fc, x - vertical, y - !vertical, c_idx) +
get_qPc(
fc, x, y, c_idx) - 2 *
sps->qp_bd_offset + 1) >> 1;
788 const int ctb_size =
fc->ps.sps->ctb_size_y;
789 const DBParams *params =
fc->tab.deblock + rs;
790 int x_end =
FFMIN(x0 + ctb_size,
fc->ps.pps->width);
791 int y_end =
FFMIN(y0 + ctb_size,
fc->ps.pps->height);
794 const uint8_t no_p[4] = { 0 };
795 const uint8_t no_q[4] = { 0 } ;
800 FFSWAP(
int, x_end, y_end);
804 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
805 const int hs = (vertical ?
sps->hshift :
sps->vshift)[c_idx];
806 const int vs = (vertical ?
sps->vshift :
sps->hshift)[c_idx];
808 const int tc_offset = params->
tc_offset[c_idx];
809 const int beta_offset = params->
beta_offset[c_idx];
810 const int src_stride =
fc->frame->linesize[c_idx];
812 for (
int y = y0; y < y_end; y += (
DEBLOCK_STEP << vs)) {
813 for (
int x = x0 ? x0 : grid; x < x_end; x += grid) {
814 const uint8_t horizontal_ctu_edge = !vertical && !(x % ctb_size);
815 int32_t bs[4], beta[4], tc[4] = { }, all_zero_bs = 1;
816 uint8_t max_len_p[4], max_len_q[4];
818 for (
int i = 0; i < DEBLOCK_STEP >> (2 - vs);
i++) {
820 int ty = y + (
i << 2);
821 const int end = ty >= y_end;
826 bs[
i] = end ? 0 :
TAB_BS(
fc->tab.bs[vertical][c_idx], tx, ty);
828 const int qp =
get_qp(
fc,
POS(c_idx, tx, ty), tx, ty, c_idx, vertical);
837 uint8_t *
src = vertical ?
POS(c_idx, x, y) :
POS(c_idx, y, x);
839 fc->vvcdsp.lf.filter_luma[vertical](
src, src_stride, beta, tc, no_p, no_q, max_len_p, max_len_q, horizontal_ctu_edge);
841 fc->vvcdsp.lf.filter_chroma[vertical](
src, src_stride, beta, tc, no_p, no_q, max_len_p, max_len_q, vs);
859 const int pixel_shift,
int width,
const int height,
const ptrdiff_t dst_stride,
const ptrdiff_t src_stride)
861 width <<= pixel_shift;
872 if (pixel_shift == 0) {
874 memset(_dst, *_src,
width);
879 const uint16_t *
src = (
const uint16_t *)_src;
880 uint16_t *dst = (uint16_t *)_dst;
884 for (
int j = 0; j <
width; j++)
895 width <<= pixel_shift;
903 const int x,
const int y,
const int width,
const int height,
const int rx,
const int ry,
const int c_idx)
905 const int ps =
fc->ps.sps->pixel_shift;
906 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
907 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
909 const int offset_h[] = { 0,
height - border_pixels };
910 const int offset_v[] = { 0,
width - border_pixels };
914 alf_copy_border(
fc->tab.alf_pixel_buffer_h[c_idx][
i] + ((border_pixels * ry *
w + x)<< ps),
915 src + offset_h[
i] * src_stride, ps,
width, border_pixels,
w << ps, src_stride);
919 alf_copy_border(
fc->tab.alf_pixel_buffer_v[c_idx][
i] + ((
h * rx + y) * (border_pixels << ps)),
920 src + (offset_v[
i] << ps), ps, border_pixels,
height, border_pixels << ps, src_stride);
924 static void alf_fill_border_h(uint8_t *dst,
const ptrdiff_t dst_stride,
const uint8_t *
src,
const ptrdiff_t src_stride,
925 const uint8_t *border,
const int width,
const int border_pixels,
const int ps,
const int edge)
934 const uint8_t *border,
const int border_pixels,
const int height,
const int pixel_shift,
const int *edges,
const int edge)
936 const ptrdiff_t src_stride = (border_pixels << pixel_shift);
945 pixel_shift, border_pixels,
height + (!edges[
TOP] + !edges[
BOTTOM]) * border_pixels, dst_stride, src_stride);
949 alf_extend_horz(dst, dst + dst_stride * border_pixels, pixel_shift, border_pixels, border_pixels, dst_stride);
953 dst += dst_stride * (border_pixels +
height);
954 alf_extend_horz(dst, dst - dst_stride, pixel_shift, border_pixels, border_pixels, dst_stride);
959 const int rx,
const int ry,
const int width,
const int height,
const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
960 const int c_idx,
const int *edges)
962 const int ps =
fc->ps.sps->pixel_shift;
963 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
964 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
971 src =
fc->tab.alf_pixel_buffer_h[c_idx][1] + (((border_pixels *
w) << ps) * (ry - 1) + (x << ps));
972 dst = _dst - border_pixels * dst_stride;
976 src =
fc->tab.alf_pixel_buffer_h[c_idx][0] + (((border_pixels *
w) << ps) * (ry + 1) + (x << ps));
977 dst = _dst +
height * dst_stride;
982 src =
fc->tab.alf_pixel_buffer_v[c_idx][1] + (
h * (rx - 1) + y - border_pixels) * (border_pixels << ps);
983 dst = _dst - (border_pixels << ps) - border_pixels * dst_stride;
987 src =
fc->tab.alf_pixel_buffer_v[c_idx][0] + (
h * (rx + 1) + y - border_pixels) * (border_pixels << ps);
988 dst = _dst + (
width << ps) - border_pixels * dst_stride;
992 #define ALF_MAX_BLOCKS_IN_CTU (MAX_CTU_SIZE * MAX_CTU_SIZE / ALF_BLOCK_SIZE / ALF_BLOCK_SIZE)
993 #define ALF_MAX_FILTER_SIZE (ALF_MAX_BLOCKS_IN_CTU * ALF_NUM_COEFF_LUMA)
1001 const int16_t *coeff_set;
1002 const uint8_t *clip_idx_set;
1003 const uint8_t *class_to_filt;
1010 clip_idx_set = &fixed_clip_set[0][0];
1015 coeff_set = &
aps->luma_coeff[0][0];
1016 clip_idx_set = &
aps->luma_clip_idx[0][0];
1019 fc->vvcdsp.alf.classify(class_idx, transpose_idx,
src, src_stride,
width,
height,
1021 fc->vvcdsp.alf.recon_coeff_and_clip(
coeff,
clip, class_idx, transpose_idx,
size,
1022 coeff_set, clip_idx_set, class_to_filt);
1026 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
const int x0,
const int y0,
1030 int vb_pos = _vb_pos - y0;
1031 int16_t *
coeff = (int16_t*)lc->
tmp;
1032 int16_t *
clip = (int16_t *)lc->
tmp1;
1044 const int offset[] = {0, 3, 5, 7};
1046 return 1 << (
sps->bit_depth -
offset[idx]);
1050 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
const int c_idx,
1057 const int16_t *
coeff =
aps->chroma_coeff[idx];
1067 const ptrdiff_t dst_stride,
const ptrdiff_t luma_stride,
const int c_idx,
1068 const int width,
const int height,
const int hs,
const int vs,
const int vb_pos,
const ALFParams *alf)
1072 const int idx = c_idx - 1;
1079 fc->vvcdsp.alf.filter_cc(dst, dst_stride, luma, luma_stride,
width,
height, hs, vs,
coeff, vb_pos);
1086 const int rx = x0 >>
fc->ps.sps->ctb_log2_size_y;
1087 const int ry = y0 >>
fc->ps.sps->ctb_log2_size_y;
1088 const int ctb_size_y =
fc->ps.sps->ctb_size_y;
1091 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
1092 const int hs =
fc->ps.sps->hshift[c_idx];
1093 const int vs =
fc->ps.sps->vshift[c_idx];
1094 const int x = x0 >> hs;
1095 const int y = y0 >> vs;
1096 const int width =
FFMIN(
fc->ps.pps->width - x0, ctb_size_y) >> hs;
1097 const int height =
FFMIN(
fc->ps.pps->height - y0, ctb_size_y) >> vs;
1099 const int src_stride =
fc->frame->linesize[c_idx];
1100 uint8_t *
src =
POS(c_idx, x0, y0);
1115 if (!
pps->r->pps_loop_filter_across_tiles_enabled_flag) {
1118 edges[
RIGHT] = edges[
RIGHT] ||
pps->ctb_to_col_bd[rx] !=
pps->ctb_to_col_bd[rx + 1];
1119 edges[
BOTTOM] = edges[
BOTTOM] ||
pps->ctb_to_row_bd[ry] !=
pps->ctb_to_row_bd[ry + 1];
1122 if (!
pps->r->pps_loop_filter_across_slices_enabled_flag) {
1125 edges[
RIGHT] = edges[
RIGHT] ||
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx + 1, ry);
1129 if (!
sps->r->sps_loop_filter_across_subpic_enabled_flag[subpic_idx]) {
1132 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;
1133 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;
1136 if (
sps->r->sps_virtual_boundaries_enabled_flag) {
1147 memcpy(sb_edges, edges,
sizeof(
int) *
MAX_EDGES);
1152 int *
pos[] = { &sb->
l, &sb->
t, &sb->
r, &sb->
b };
1154 for (
int vertical = 0; vertical <= 1; vertical++) {
1155 if (has_vb[vertical]) {
1157 *
pos[
c] = vb_pos[vertical];
1164 const int x0,
const int y0,
const int rx,
const int ry)
1169 const int ctu_size_y =
sps->ctb_size_y;
1171 const int has_vb[] = { vb_pos[0] > y0, vb_pos[1] > x0 };
1173 int edges[
MAX_EDGES] = { !rx, !ry, rx ==
pps->ctb_width - 1, ry ==
pps->ctb_height - 1 };
1178 for (
int by = 0; by <= has_vb[0]; by++) {
1179 for (
int bx = 0; bx <= has_vb[1]; bx++,
i++) {
1191 const int rx = x0 >>
sps->ctb_log2_size_y;
1192 const int ry = y0 >>
sps->ctb_log2_size_y;
1193 const int ps =
sps->pixel_shift;
1197 const int ctu_end = y0 +
sps->ctb_size_y;
1204 for (
int i = 0;
i < nb_sbs;
i++) {
1206 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
1207 const int hs =
fc->ps.sps->hshift[c_idx];
1208 const int vs =
fc->ps.sps->vshift[c_idx];
1209 const int x = sb->
l >> hs;
1210 const int y = sb->
t >> vs;
1211 const int width = (sb->
r - sb->
l) >> hs;
1212 const int height = (sb->
b - sb->
t) >> vs;
1213 const int src_stride =
fc->frame->linesize[c_idx];
1214 uint8_t *
src =
POS(c_idx, sb->
l, sb->
t);
1220 padded_stride, src_stride, c_idx, sb_edges[
i]);
1245 const int ctb_size =
fc->ps.sps->ctb_size_y;
1246 const int width =
FFMIN(
fc->ps.pps->width - x, ctb_size);