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++) {
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);
288 copy_vert(
dst - (1 << ps), sao_v + (((2 * rx - 1) *
h + y) << ps), ps,
height, dst_stride, 1 << ps);
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) >> MIN_TU_LOG2) * (fc->ps.pps->min_tu_width) + ((x) >> MIN_TU_LOG2)]
376 #define TAB_MAX_LEN(t, x, y) (t)[((y) >> MIN_TU_LOG2) * (fc->ps.pps->min_tu_width) + ((x) >> MIN_TU_LOG2)]
379 #define DEBLOCK_STEP 8
381 #define CHROMA_GRID 8
440 if (ref_A == ref_B) {
454 const int size_q,
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];
460 const int min_cb_log2 =
fc->ps.sps->min_cb_log2_size_y;
461 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;
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 cb_p = (y_p >> log2_min_cb_size) * min_cb_width + (x_p >> log2_min_cb_size);
557 return fc->tab.tu_coded_flag[c_idx][tu_p] ||
558 fc->tab.tu_joint_cbcr_residual_flag[tu_p] ||
566 if ((off_to_cb && ((off_to_cb % 8) || !has_sub_block)))
576 const int pos,
const int rs,
const int vertical)
582 if (boundary && (
pos %
fc->ps.sps->ctb_size_y) == 0) {
595 const int q_rs = rs - (vertical ? 1 :
fc->ps.pps->ctb_width);
607 const int x0,
const int y0,
const int width,
const int height,
613 const int pos = vertical ? x0 : y0;
614 const int cb = vertical ? cu->
x0 : cu->
y0;
623 const int off =
cb -
pos;
628 for (
int i = 0;
i <
size;
i += 4) {
629 const int x = x0 +
i * !vertical;
630 const int y = y0 +
i * vertical;
631 uint8_t max_len_p, max_len_q;
632 const int bs = is_vb ? 0 :
deblock_bs(lc, x - vertical, y - !vertical, x, y, cu, tu, rpl_p,
LUMA, off, has_sb);
647 const int x0,
const int y0,
const int width,
const int height,
651 const int shift = (vertical ?
fc->ps.sps->hshift :
fc->ps.sps->vshift)[
CHROMA];
653 const int pos = vertical ? x0 : y0;
659 for (
int c_idx =
CB; c_idx <=
CR; c_idx++) {
660 for (
int i = 0;
i <
size;
i += 2) {
661 const int x = x0 +
i * !vertical;
662 const int y = y0 +
i * vertical;
663 const int bs = is_vb ? 0 :
deblock_bs(lc, x - vertical, y - !vertical, x, y, cu, tu,
NULL, c_idx, 0, 0);
665 TAB_BS(
fc->tab.bs[vertical][c_idx], x, y) = bs;
672 const int width,
const int height,
const int rs,
const int vertical);
678 const int x0 = rx <<
sps->ctb_log2_size_y;
679 const int y0 = ry <<
sps->ctb_log2_size_y;
682 for (
const CodingUnit *cu =
fc->tab.cus[rs]; cu; cu = cu->next) {
684 for (
int vertical = 0; vertical <= 1; vertical++) {
700 const int vertical, uint8_t *max_len_p, uint8_t *max_len_q)
702 *max_len_p =
TAB_MAX_LEN(
fc->tab.max_len_p[vertical], qx, qy);
703 *max_len_q =
TAB_MAX_LEN(
fc->tab.max_len_q[vertical], qx, qy);
708 const int vertical,
const int horizontal_ctu_edge,
const int bs, uint8_t *max_len_p, uint8_t *max_len_q)
710 const int px = vertical ? qx - 1 : qx;
711 const int py = !vertical ? qy - 1 : qy;
712 const uint8_t *tb_size = vertical ?
fc->tab.tb_width[
CHROMA] :
fc->tab.tb_height[
CHROMA];
716 if (size_p >= 8 && size_q >= 8) {
717 *max_len_p = *max_len_q = 3;
718 if (horizontal_ctu_edge)
722 *max_len_p = *max_len_q = (bs == 2);
727 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)
735 #define TC_CALC(qp, bs) \
736 tctable[av_clip((qp) + DEFAULT_INTRA_TC_OFFSET * ((bs) - 1) + \
738 0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)]
748 if (!
sps->r->sps_ladf_enabled_flag)
752 qp_offset =
sps->r->sps_ladf_lowest_interval_qp_offset;
753 for (
int i = 0;
i <
sps->num_ladf_intervals - 1 &&
level >
sps->ladf_interval_lower_bound[
i + 1];
i++)
754 qp_offset =
sps->r->sps_ladf_qp_offset[
i];
756 return qp + qp_offset;
763 return (
get_qPc(
fc, x - vertical, y - !vertical, c_idx) +
get_qPc(
fc, x, y, c_idx) - 2 *
sps->qp_bd_offset + 1) >> 1;
778 const int ctb_size =
fc->ps.sps->ctb_size_y;
779 const DBParams *params =
fc->tab.deblock + rs;
780 int x_end =
FFMIN(x0 + ctb_size,
fc->ps.pps->width);
781 int y_end =
FFMIN(y0 + ctb_size,
fc->ps.pps->height);
784 const uint8_t no_p[4] = { 0 };
785 const uint8_t no_q[4] = { 0 } ;
788 FFSWAP(
int, x_end, y_end);
792 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
793 const int hs = (vertical ?
sps->hshift :
sps->vshift)[c_idx];
794 const int vs = (vertical ?
sps->vshift :
sps->hshift)[c_idx];
796 const int tc_offset = params->
tc_offset[c_idx];
797 const int beta_offset = params->
beta_offset[c_idx];
798 const int src_stride =
fc->frame->linesize[c_idx];
800 for (
int y = y0; y < y_end; y += (
DEBLOCK_STEP << vs)) {
801 for (
int x = x0 ? x0 : grid; x < x_end; x += grid) {
802 const uint8_t horizontal_ctu_edge = !vertical && !(x % ctb_size);
803 int32_t bs[4], beta[4], tc[4] = { 0 }, all_zero_bs = 1;
804 uint8_t max_len_p[4], max_len_q[4];
806 for (
int i = 0; i < DEBLOCK_STEP >> (2 - vs);
i++) {
808 int ty = y + (
i << 2);
809 const int end = ty >= y_end;
814 bs[
i] = end ? 0 :
TAB_BS(
fc->tab.bs[vertical][c_idx], tx, ty);
816 const int qp =
get_qp(
fc,
POS(c_idx, tx, ty), tx, ty, c_idx, vertical);
825 uint8_t *
src = vertical ?
POS(c_idx, x, y) :
POS(c_idx, y, x);
827 fc->vvcdsp.lf.filter_luma[vertical](
src, src_stride, beta, tc, no_p, no_q, max_len_p, max_len_q, horizontal_ctu_edge);
829 fc->vvcdsp.lf.filter_chroma[vertical](
src, src_stride, beta, tc, no_p, no_q, max_len_p, max_len_q, vs);
847 const int pixel_shift,
int width,
const int height,
const ptrdiff_t dst_stride,
const ptrdiff_t src_stride)
849 width <<= pixel_shift;
860 if (pixel_shift == 0) {
867 const uint16_t *
src = (
const uint16_t *)
_src;
868 uint16_t *
dst = (uint16_t *)
_dst;
872 for (
int j = 0; j <
width; j++)
883 width <<= pixel_shift;
891 const int x,
const int y,
const int width,
const int height,
const int rx,
const int ry,
const int c_idx)
893 const int ps =
fc->ps.sps->pixel_shift;
894 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
895 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
897 const int offset_h[] = { 0,
height - border_pixels };
898 const int offset_v[] = { 0,
width - border_pixels };
902 alf_copy_border(
fc->tab.alf_pixel_buffer_h[c_idx][
i] + ((border_pixels * ry *
w + x)<< ps),
903 src + offset_h[
i] * src_stride, ps,
width, border_pixels,
w << ps, src_stride);
907 alf_copy_border(
fc->tab.alf_pixel_buffer_v[c_idx][
i] + ((
h * rx + y) * (border_pixels << ps)),
908 src + (offset_v[
i] << ps), ps, border_pixels,
height, border_pixels << ps, src_stride);
913 const uint8_t *border,
const int width,
const int border_pixels,
const int ps,
const int edge)
922 const uint8_t *border,
const int border_pixels,
const int height,
const int pixel_shift,
const int *edges,
const int edge)
924 const ptrdiff_t src_stride = (border_pixels << pixel_shift);
933 pixel_shift, border_pixels,
height + (!edges[
TOP] + !edges[
BOTTOM]) * border_pixels, dst_stride, src_stride);
937 alf_extend_horz(
dst,
dst + dst_stride * border_pixels, pixel_shift, border_pixels, border_pixels, dst_stride);
941 dst += dst_stride * (border_pixels +
height);
947 const int rx,
const int ry,
const int width,
const int height,
const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
948 const int c_idx,
const int *edges)
950 const int ps =
fc->ps.sps->pixel_shift;
951 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
952 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
959 src =
fc->tab.alf_pixel_buffer_h[c_idx][1] + (((border_pixels *
w) << ps) * (ry - 1) + (x << ps));
960 dst =
_dst - border_pixels * dst_stride;
964 src =
fc->tab.alf_pixel_buffer_h[c_idx][0] + (((border_pixels *
w) << ps) * (ry + 1) + (x << ps));
970 src =
fc->tab.alf_pixel_buffer_v[c_idx][1] + (
h * (rx - 1) + y - border_pixels) * (border_pixels << ps);
971 dst =
_dst - (border_pixels << ps) - border_pixels * dst_stride;
975 src =
fc->tab.alf_pixel_buffer_v[c_idx][0] + (
h * (rx + 1) + y - border_pixels) * (border_pixels << ps);
976 dst =
_dst + (
width << ps) - border_pixels * dst_stride;
980 #define ALF_MAX_BLOCKS_IN_CTU (MAX_CTU_SIZE * MAX_CTU_SIZE / ALF_BLOCK_SIZE / ALF_BLOCK_SIZE)
981 #define ALF_MAX_FILTER_SIZE (ALF_MAX_BLOCKS_IN_CTU * ALF_NUM_COEFF_LUMA)
989 const int16_t *coeff_set;
990 const uint8_t *clip_idx_set;
991 const uint8_t *class_to_filt;
998 clip_idx_set = &fixed_clip_set[0][0];
1003 coeff_set = &
aps->luma_coeff[0][0];
1004 clip_idx_set = &
aps->luma_clip_idx[0][0];
1007 fc->vvcdsp.alf.classify(class_idx, transpose_idx,
src, src_stride,
width,
height,
1009 fc->vvcdsp.alf.recon_coeff_and_clip(
coeff,
clip, class_idx, transpose_idx,
size,
1010 coeff_set, clip_idx_set, class_to_filt);
1014 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
const int x0,
const int y0,
1018 int vb_pos = _vb_pos - y0;
1019 int16_t *
coeff = (int16_t*)lc->
tmp;
1020 int16_t *
clip = (int16_t *)lc->
tmp1;
1032 const int offset[] = {0, 3, 5, 7};
1034 return 1 << (
sps->bit_depth -
offset[idx]);
1038 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
const int c_idx,
1045 const int16_t *
coeff =
aps->chroma_coeff[idx];
1055 const ptrdiff_t dst_stride,
const ptrdiff_t luma_stride,
const int c_idx,
1056 const int width,
const int height,
const int hs,
const int vs,
const int vb_pos,
const ALFParams *alf)
1060 const int idx = c_idx - 1;
1074 const int rx = x0 >>
fc->ps.sps->ctb_log2_size_y;
1075 const int ry = y0 >>
fc->ps.sps->ctb_log2_size_y;
1076 const int ctb_size_y =
fc->ps.sps->ctb_size_y;
1079 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
1080 const int hs =
fc->ps.sps->hshift[c_idx];
1081 const int vs =
fc->ps.sps->vshift[c_idx];
1082 const int x = x0 >> hs;
1083 const int y = y0 >> vs;
1084 const int width =
FFMIN(
fc->ps.pps->width - x0, ctb_size_y) >> hs;
1085 const int height =
FFMIN(
fc->ps.pps->height - y0, ctb_size_y) >> vs;
1087 const int src_stride =
fc->frame->linesize[c_idx];
1088 uint8_t *
src =
POS(c_idx, x0, y0);
1103 if (!
pps->r->pps_loop_filter_across_tiles_enabled_flag) {
1106 edges[
RIGHT] = edges[
RIGHT] ||
pps->ctb_to_col_bd[rx] !=
pps->ctb_to_col_bd[rx + 1];
1107 edges[
BOTTOM] = edges[
BOTTOM] ||
pps->ctb_to_row_bd[ry] !=
pps->ctb_to_row_bd[ry + 1];
1110 if (!
pps->r->pps_loop_filter_across_slices_enabled_flag) {
1113 edges[
RIGHT] = edges[
RIGHT] ||
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx + 1, ry);
1117 if (!
sps->r->sps_loop_filter_across_subpic_enabled_flag[subpic_idx]) {
1120 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;
1121 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;
1124 if (
sps->r->sps_virtual_boundaries_enabled_flag) {
1135 memcpy(sb_edges, edges,
sizeof(
int) *
MAX_EDGES);
1140 int *
pos[] = { &sb->
l, &sb->
t, &sb->
r, &sb->
b };
1142 for (
int vertical = 0; vertical <= 1; vertical++) {
1143 if (has_vb[vertical]) {
1145 *
pos[
c] = vb_pos[vertical];
1152 const int x0,
const int y0,
const int rx,
const int ry)
1157 const int ctu_size_y =
sps->ctb_size_y;
1159 const int has_vb[] = { vb_pos[0] > y0, vb_pos[1] > x0 };
1161 int edges[
MAX_EDGES] = { !rx, !ry, rx ==
pps->ctb_width - 1, ry ==
pps->ctb_height - 1 };
1166 for (
int by = 0; by <= has_vb[0]; by++) {
1167 for (
int bx = 0; bx <= has_vb[1]; bx++,
i++) {
1179 const int rx = x0 >>
sps->ctb_log2_size_y;
1180 const int ry = y0 >>
sps->ctb_log2_size_y;
1181 const int ps =
sps->pixel_shift;
1185 const int has_chroma = !!
sps->r->sps_chroma_format_idc;
1186 const int ctu_end = y0 +
sps->ctb_size_y;
1193 for (
int i = 0;
i < nb_sbs;
i++) {
1195 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
1196 const int hs =
fc->ps.sps->hshift[c_idx];
1197 const int vs =
fc->ps.sps->vshift[c_idx];
1198 const int x = sb->
l >> hs;
1199 const int y = sb->
t >> vs;
1200 const int width = (sb->
r - sb->
l) >> hs;
1201 const int height = (sb->
b - sb->
t) >> vs;
1202 const int src_stride =
fc->frame->linesize[c_idx];
1203 uint8_t *
src =
POS(c_idx, sb->
l, sb->
t);
1209 padded_stride, src_stride, c_idx, sb_edges[
i]);
1234 const int ctb_size =
fc->ps.sps->ctb_size_y;
1235 const int width =
FFMIN(
fc->ps.pps->width - x, ctb_size);