37#define DEFAULT_INTRA_TC_OFFSET 2
39#define POS(c_idx, x, y) \
40 &fc->frame->data[c_idx][((y) >> fc->ps.sps->vshift[c_idx]) * fc->frame->linesize[c_idx] + \
41 (((x) >> fc->ps.sps->hshift[c_idx]) << fc->ps.sps->pixel_shift)]
45 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 0, 0, 3, 4, 4, 4, 4, 5, 5, 5, 5, 7, 7, 8, 9, 10,
47 10, 11, 13, 14, 15, 17, 19, 21, 24, 25, 29, 33, 36, 41, 45, 51,
48 57, 64, 71, 80, 89, 100, 112, 125, 141, 157, 177, 198, 222, 250, 280, 314,
54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24,
56 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56,
57 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88,
67 const uint16_t *vbs = vertical ?
ph->vb_pos_x :
ph->vb_pos_y;
68 const uint8_t nb_vbs = vertical ?
ph->num_ver_vbs :
ph->num_hor_vbs;
69 const int pos = ctu_pos <<
sps->ctb_log2_size_y;
71 if (
sps->r->sps_virtual_boundaries_enabled_flag) {
72 for (
int i = 0;
i < nb_vbs;
i++) {
73 const int o = vbs[
i] -
pos;
74 if (o >= 0 && o < sps->ctb_size_y)
90 const int min_tu_width =
fc->ps.pps->min_tu_width;
91 return fc->tab.qp[
chroma][x + y * min_tu_width];
95 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride)
97 for (
int y = 0; y <
height; y++) {
108 *(uint16_t *)
dst = *(uint16_t *)
src;
114 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride)
117 if (pixel_shift == 0) {
125 *(uint16_t *)
dst = *(uint16_t *)
src;
133 const ptrdiff_t src_stride,
const int x,
const int y,
const int width,
const int height,
134 const int c_idx,
const int rx,
const int ry,
const int top)
136 const int ps =
fc->ps.sps->pixel_shift;
137 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
138 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
142 memcpy(
fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry) *
w + x) << ps),
146 memcpy(
fc->tab.sao_pixel_buffer_h[c_idx] + (((2 * ry + 1) *
w + x) << ps),
150 copy_vert(
fc->tab.sao_pixel_buffer_v[c_idx] + (((2 * rx) *
h + y) << ps),
src, ps,
height, 1 << ps, src_stride);
151 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);
158 const int ctb_size_y =
fc->ps.sps->ctb_size_y;
159 const int x0 = rx <<
fc->ps.sps->ctb_log2_size_y;
160 const int y0 = ry <<
fc->ps.sps->ctb_log2_size_y;
162 for (
int c_idx = 0; c_idx < (
fc->ps.sps->r->sps_chroma_format_idc ? 3 : 1); c_idx++) {
163 const int x = x0 >>
fc->ps.sps->hshift[c_idx];
164 const int y = y0 >>
fc->ps.sps->vshift[c_idx];
165 const ptrdiff_t src_stride =
fc->frame->linesize[c_idx];
166 const int ctb_size_h = ctb_size_y >>
fc->ps.sps->hshift[c_idx];
167 const int ctb_size_v = ctb_size_y >>
fc->ps.sps->vshift[c_idx];
168 const int width =
FFMIN(ctb_size_h, (
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx]) - x);
169 const int height =
FFMIN(ctb_size_v, (
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx]) - y);
170 const uint8_t *
src =
POS(c_idx, x0, y0);
171 copy_ctb_to_hv(
fc,
src, src_stride, x, y,
width,
height, c_idx, rx, ry, top);
188 const uint8_t lfase =
fc->ps.pps->r->pps_loop_filter_across_slices_enabled_flag;
190 return lfase ||
CTB(
fc->tab.slice_idx, rx, ry) ==
CTB(
fc->tab.slice_idx, rx + dx, ry + dy);
193static void sao_get_edges(uint8_t vert_edge[2], uint8_t horiz_edge[2], uint8_t diag_edge[4],
int *restore,
194 const VVCLocalContext *lc,
const int edges[4],
const int rx,
const int ry)
201 const uint8_t lfase =
fc->ps.pps->r->pps_loop_filter_across_slices_enabled_flag;
202 const uint8_t no_tile_filter =
pps->r->num_tiles_in_pic > 1 && !
pps->r->pps_loop_filter_across_tiles_enabled_flag;
204 uint8_t lf_edge[] = { 0, 0, 0, 0 };
212 lf_edge[
LEFT] = no_tile_filter &&
pps->ctb_to_col_bd[rx] == rx;
218 lf_edge[
RIGHT] = no_tile_filter &&
pps->ctb_to_col_bd[rx] !=
pps->ctb_to_col_bd[rx + 1];
224 lf_edge[
TOP] = no_tile_filter &&
pps->ctb_to_row_bd[ry] == ry;
230 lf_edge[
BOTTOM] = no_tile_filter &&
pps->ctb_to_row_bd[ry] !=
pps->ctb_to_row_bd[ry + 1];
236 if (!edges[
LEFT] && !edges[
TOP])
250 const uint8_t *
src,
const ptrdiff_t src_stride,
const int width,
const int edges[4],
const int ps)
253 const int right = 1 - edges[
RIGHT];
271 const uint8_t *
src,
const ptrdiff_t src_stride,
const int width,
const int height,
272 const VVCFrameContext *
fc,
const int x0,
const int y0,
const int rx,
const int ry,
const int edges[4],
const int c_idx)
274 const uint8_t *sao_h =
fc->tab.sao_pixel_buffer_h[c_idx];
275 const uint8_t *sao_v =
fc->tab.sao_pixel_buffer_v[c_idx];
276 const int x = x0 >>
fc->ps.sps->hshift[c_idx];
277 const int y = y0 >>
fc->ps.sps->vshift[c_idx];
278 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
279 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
280 const int ps =
fc->ps.sps->pixel_shift;
283 sao_copy_hor(
dst - dst_stride, dst_stride, sao_h + (((2 * ry - 1) *
w + x) << ps), src_stride,
width, edges, ps);
289 copy_vert(
dst - (1 << ps), sao_v + (((2 * rx - 1) *
h + y) << ps), ps,
height, dst_stride, 1 << ps);
298 const int width,
const int height,
const int vb_pos,
const int ps,
const int vertical)
309 dst += dy * dst_stride +(dx << ps);
310 src += dy * src_stride +(dx << ps);
319 const int rx = x0 >>
sps->ctb_log2_size_y;
320 const int ry = y0 >>
sps->ctb_log2_size_y;
321 const int edges[4] = { !rx, !ry, rx ==
fc->ps.pps->ctb_width - 1, ry ==
fc->ps.pps->ctb_height - 1 };
324 uint8_t vert_edge[] = { 0, 0 };
325 uint8_t horiz_edge[] = { 0, 0 };
326 uint8_t diag_edge[] = { 0, 0, 0, 0 };
327 int restore, vb_x = 0, vb_y = 0;;
329 if (
sps->r->sps_virtual_boundaries_enabled_flag) {
334 sao_get_edges(vert_edge, horiz_edge, diag_edge, &restore, lc, edges, rx, ry);
336 for (
int c_idx = 0; c_idx < (
sps->r->sps_chroma_format_idc ? 3 : 1); c_idx++) {
337 static const uint8_t sao_tab[16] = { 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8 };
338 const ptrdiff_t src_stride =
fc->frame->linesize[c_idx];
339 uint8_t *
src =
POS(c_idx, x0, y0);
340 const int hs =
sps->hshift[c_idx];
341 const int vs =
sps->vshift[c_idx];
342 const int ps =
sps->pixel_shift;
343 const int width =
FFMIN(
sps->ctb_size_y,
fc->ps.pps->width - x0) >> hs;
346 const int sao_eo_class = sao->
eo_class[c_idx];
350 fc->vvcdsp.sao.band_filter[
tab](
src,
src, src_stride, src_stride,
358 sao_extends_edges(
dst, dst_stride,
src, src_stride,
width,
height,
fc, x0, y0, rx, ry, edges, c_idx);
362 fc->vvcdsp.sao.edge_restore[restore](
src,
dst, src_stride, dst_stride,
363 sao, edges,
width,
height, c_idx, vert_edge, horiz_edge, diag_edge);
376#define TAB_BS(t, x, y) (t)[((y) >> MIN_TU_LOG2) * (fc->ps.pps->min_tu_width) + ((x) >> MIN_TU_LOG2)]
377#define TAB_MAX_LEN(t, x, y) (t)[((y) >> MIN_TU_LOG2) * (fc->ps.pps->min_tu_width) + ((x) >> MIN_TU_LOG2)]
380#define DEBLOCK_STEP 8
444 if (ref_A == ref_B) {
458 const int size_q,
const int has_subblock,
const int vertical, uint8_t *max_len_p, uint8_t *max_len_q)
460 const int px = vertical ? qx - 1 : qx;
461 const int py = !vertical ? qy - 1 : qy;
462 const uint8_t *tb_size = vertical ?
fc->tab.tb_width[
LUMA] :
fc->tab.tb_height[
LUMA];
464 const int min_cb_log2 =
fc->ps.sps->min_cb_log2_size_y;
465 const int off_p = (py >> min_cb_log2) *
fc->ps.pps->min_cb_width + (px >> min_cb_log2);
467 if (size_p <= 4 || size_q <= 4) {
468 *max_len_p = *max_len_q = 1;
470 *max_len_p = *max_len_q = 3;
477 *max_len_q =
FFMIN(5, *max_len_q);
478 if (
fc->tab.msf[off_p] ||
fc->tab.iaf[off_p])
479 *max_len_p =
FFMIN(5, *max_len_p);
483 const int cb,
int x0,
int y0,
int width,
int height,
const int vertical)
488 int stridea =
fc->ps.pps->min_pu_width;
495 FFSWAP(
int, stridea, strideb);
499 for (
int i = 8 - ((x0 -
cb) % 8);
i <
width;
i += 8) {
501 const int xp_pu = (x0 +
i - 1) >> log2_min_pu_size;
502 const int xq_pu = (x0 +
i) >> log2_min_pu_size;
504 for (
int j = 0; j <
height; j += 4) {
505 const int y_pu = (y0 + j) >> log2_min_pu_size;
506 const MvField *mvf_p = &tab_mvf[y_pu * stridea + xp_pu * strideb];
507 const MvField *mvf_q = &tab_mvf[y_pu * stridea + xq_pu * strideb];
511 uint8_t max_len_p = 0, max_len_q = 0;
519 max_len_p = max_len_q = 1;
520 else if (
i == 8 ||
i ==
width - 8)
521 max_len_p = max_len_q = 2;
523 max_len_p = max_len_q = 3;
533 const RefPicList *rpl_p,
const int c_idx,
const int off_to_cb,
const uint8_t has_sub_block)
539 const int log2_min_cb_size =
fc->ps.sps->min_cb_log2_size_y;
540 const int min_pu_width =
fc->ps.pps->min_pu_width;
541 const int min_tu_width =
fc->ps.pps->min_tu_width;
542 const int min_cb_width =
fc->ps.pps->min_cb_width;
543 const int pu_p = (y_p >> log2_min_pu_size) * min_pu_width + (x_p >> log2_min_pu_size);
544 const int pu_q = (y_q >> log2_min_pu_size) * min_pu_width + (x_q >> log2_min_pu_size);
545 const MvField *mvf_p = &tab_mvf[pu_p];
546 const MvField *mvf_q = &tab_mvf[pu_q];
547 const uint8_t
chroma = !!c_idx;
548 const int tu_p = (y_p >> log2_min_tu_size) * min_tu_width + (x_p >> log2_min_tu_size);
549 const int cb_p = (y_p >> log2_min_cb_size) * min_cb_width + (x_p >> log2_min_cb_size);
561 return fc->tab.tu_coded_flag[c_idx][tu_p] ||
562 fc->tab.tu_joint_cbcr_residual_flag[tu_p] ||
570 if ((off_to_cb && ((off_to_cb % 8) || !has_sub_block)))
580 const int pos,
const int rs,
const int vertical)
586 if (boundary && (
pos %
fc->ps.sps->ctb_size_y) == 0) {
599 const int q_rs = rs - (vertical ? 1 :
fc->ps.pps->ctb_width);
611 const int x0,
const int y0,
const int width,
const int height,
617 const int pos = vertical ? x0 : y0;
618 const int cb = vertical ? cu->
x0 : cu->
y0;
627 const int off =
cb -
pos;
632 for (
int i = 0;
i <
size;
i += 4) {
633 const int x = x0 +
i * !vertical;
634 const int y = y0 +
i * vertical;
635 uint8_t max_len_p, max_len_q;
636 const int bs = is_vb ? 0 :
deblock_bs(lc, x - vertical, y - !vertical, x, y, cu, tu, rpl_p,
LUMA, off, has_sb);
651 const int x0,
const int y0,
const int width,
const int height,
655 const int shift = (vertical ?
fc->ps.sps->hshift :
fc->ps.sps->vshift)[
CHROMA];
657 const int pos = vertical ? x0 : y0;
663 for (
int c_idx =
CB; c_idx <=
CR; c_idx++) {
664 for (
int i = 0;
i <
size;
i += 2) {
665 const int x = x0 +
i * !vertical;
666 const int y = y0 +
i * vertical;
667 const int bs = is_vb ? 0 :
deblock_bs(lc, x - vertical, y - !vertical, x, y, cu, tu,
NULL, c_idx, 0, 0);
669 TAB_BS(
fc->tab.bs[vertical][c_idx], x, y) = bs;
676 const int width,
const int height,
const int rs,
const int vertical);
682 const int x0 = rx <<
sps->ctb_log2_size_y;
683 const int y0 = ry <<
sps->ctb_log2_size_y;
686 for (
const CodingUnit *cu =
fc->tab.cus[rs]; cu; cu = cu->next) {
688 for (
int vertical = 0; vertical <= 1; vertical++) {
704 const int vertical, uint8_t *max_len_p, uint8_t *max_len_q)
706 *max_len_p =
TAB_MAX_LEN(
fc->tab.max_len_p[vertical], qx, qy);
707 *max_len_q =
TAB_MAX_LEN(
fc->tab.max_len_q[vertical], qx, qy);
712 const int vertical,
const int horizontal_ctu_edge,
const int bs, uint8_t *max_len_p, uint8_t *max_len_q)
714 const int px = vertical ? qx - 1 : qx;
715 const int py = !vertical ? qy - 1 : qy;
716 const uint8_t *tb_size = vertical ?
fc->tab.tb_width[
CHROMA] :
fc->tab.tb_height[
CHROMA];
720 if (size_p >= 8 && size_q >= 8) {
721 *max_len_p = *max_len_q = 3;
722 if (horizontal_ctu_edge)
726 *max_len_p = *max_len_q = (bs == 2);
731 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)
739#define TC_CALC(qp, bs) \
740 tctable[av_clip((qp) + DEFAULT_INTRA_TC_OFFSET * ((bs) - 1) + \
742 0, MAX_QP + DEFAULT_INTRA_TC_OFFSET)]
752 if (!
sps->r->sps_ladf_enabled_flag)
756 qp_offset =
sps->r->sps_ladf_lowest_interval_qp_offset;
757 for (
int i = 0;
i <
sps->num_ladf_intervals - 1 &&
level >
sps->ladf_interval_lower_bound[
i + 1];
i++)
758 qp_offset =
sps->r->sps_ladf_qp_offset[
i];
760 return qp + qp_offset;
767 return (
get_qPc(
fc, x - vertical, y - !vertical, c_idx) +
get_qPc(
fc, x, y, c_idx) - 2 *
sps->qp_bd_offset + 1) >> 1;
782 const int ctb_size =
fc->ps.sps->ctb_size_y;
784 int x_end =
FFMIN(x0 + ctb_size,
fc->ps.pps->width);
785 int y_end =
FFMIN(y0 + ctb_size,
fc->ps.pps->height);
786 const int log2_min_cb_size =
fc->ps.sps->min_cb_log2_size_y;
787 const int min_cb_width =
fc->ps.pps->min_cb_width;
790 FFSWAP(
int, x_end, y_end);
794 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
795 const int hs = (vertical ?
sps->hshift :
sps->vshift)[c_idx];
796 const int vs = (vertical ?
sps->vshift :
sps->hshift)[c_idx];
798 const int tc_offset =
params->tc_offset[c_idx];
799 const int beta_offset =
params->beta_offset[c_idx];
800 const int src_stride =
fc->frame->linesize[c_idx];
802 for (
int y = y0; y < y_end; y += (
DEBLOCK_STEP << vs)) {
803 for (
int x = x0 ? x0 : grid; x < x_end; x += grid) {
804 const uint8_t horizontal_ctu_edge = !vertical && !(x % ctb_size);
805 int32_t bs[4], beta[4], tc[4] = { 0 }, all_zero_bs = 1;
806 uint8_t max_len_p[4], max_len_q[4];
807 uint8_t no_p[4] = { 0 };
808 uint8_t no_q[4] = { 0 };
812 int ty = y + (
i << 2);
813 const int end = ty >= y_end;
818 bs[
i] = end ? 0 :
TAB_BS(
fc->tab.bs[vertical][c_idx], tx, ty);
820 const int qp =
get_qp(
fc,
POS(c_idx, tx, ty), tx, ty, c_idx, vertical);
826 if (
sps->r->sps_palette_enabled_flag) {
827 const int cu_q = (ty >> log2_min_cb_size) * min_cb_width + (tx >> log2_min_cb_size);
828 const int cu_p = (ty - !vertical >> log2_min_cb_size) * min_cb_width + (tx - vertical >> log2_min_cb_size);
830 no_p[
i] = cu_p >= 0 &&
fc->tab.cpm[!!c_idx][cu_p] ==
MODE_PLT;
836 uint8_t *
src = vertical ?
POS(c_idx, x, y) :
POS(c_idx, y, x);
838 fc->vvcdsp.lf.filter_luma[vertical](
src, src_stride, beta, tc, no_p, no_q, max_len_p, max_len_q, horizontal_ctu_edge);
840 fc->vvcdsp.lf.filter_chroma[vertical](
src, src_stride, beta, tc, no_p, no_q, max_len_p, max_len_q, vs);
858 const int pixel_shift,
int width,
const int height,
const ptrdiff_t dst_stride,
const ptrdiff_t src_stride)
860 width <<= pixel_shift;
871 if (pixel_shift == 0) {
878 const uint16_t *
src = (
const uint16_t *)
_src;
879 uint16_t *
dst = (uint16_t *)
_dst;
883 for (
int j = 0; j <
width; j++)
894 width <<= pixel_shift;
902 const int x,
const int y,
const int width,
const int height,
const int rx,
const int ry,
const int c_idx)
904 const int ps =
fc->ps.sps->pixel_shift;
905 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
906 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
908 const int offset_h[] = { 0,
height - border_pixels };
909 const int offset_v[] = { 0,
width - border_pixels };
913 alf_copy_border(
fc->tab.alf_pixel_buffer_h[c_idx][
i] + ((border_pixels * ry *
w + x)<< ps),
914 src + offset_h[
i] * src_stride, ps,
width, border_pixels,
w << ps, src_stride);
918 alf_copy_border(
fc->tab.alf_pixel_buffer_v[c_idx][
i] + ((
h * rx + y) * (border_pixels << ps)),
919 src + (offset_v[
i] << ps), ps, border_pixels,
height, border_pixels << ps, src_stride);
924 const uint8_t *border,
const int width,
const int border_pixels,
const int ps,
const int edge)
933 const uint8_t *border,
const int border_pixels,
const int height,
const int pixel_shift,
const int *edges,
const int edge)
935 const ptrdiff_t src_stride = (border_pixels << pixel_shift);
944 pixel_shift, border_pixels,
height + (!edges[
TOP] + !edges[
BOTTOM]) * border_pixels, dst_stride, src_stride);
948 alf_extend_horz(
dst,
dst + dst_stride * border_pixels, pixel_shift, border_pixels, border_pixels, dst_stride);
952 dst += dst_stride * (border_pixels +
height);
958 const int rx,
const int ry,
const int width,
const int height,
const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
959 const int c_idx,
const int *edges)
961 const int ps =
fc->ps.sps->pixel_shift;
962 const int w =
fc->ps.pps->width >>
fc->ps.sps->hshift[c_idx];
963 const int h =
fc->ps.pps->height >>
fc->ps.sps->vshift[c_idx];
970 src =
fc->tab.alf_pixel_buffer_h[c_idx][1] + (((border_pixels *
w) << ps) * (ry - 1) + (x << ps));
971 dst =
_dst - border_pixels * dst_stride;
975 src =
fc->tab.alf_pixel_buffer_h[c_idx][0] + (((border_pixels *
w) << ps) * (ry + 1) + (x << ps));
981 src =
fc->tab.alf_pixel_buffer_v[c_idx][1] + (
h * (rx - 1) + y - border_pixels) * (border_pixels << ps);
982 dst =
_dst - (border_pixels << ps) - border_pixels * dst_stride;
986 src =
fc->tab.alf_pixel_buffer_v[c_idx][0] + (
h * (rx + 1) + y - border_pixels) * (border_pixels << ps);
987 dst =
_dst + (
width << ps) - border_pixels * dst_stride;
997 const int16_t *coeff_set;
998 const uint8_t *clip_idx_set;
999 const uint8_t *class_to_filt;
1006 clip_idx_set = &fixed_clip_set[0][0];
1011 coeff_set = &
aps->luma_coeff[0][0];
1012 clip_idx_set = &
aps->luma_clip_idx[0][0];
1015 fc->vvcdsp.alf.classify(class_idx, transpose_idx,
src, src_stride,
width,
height,
1017 fc->vvcdsp.alf.recon_coeff_and_clip(
coeff,
clip, class_idx, transpose_idx,
size,
1018 coeff_set, clip_idx_set, class_to_filt);
1022 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
const int x0,
const int y0,
1026 int vb_pos = _vb_pos - y0;
1037 const int offset[] = {0, 3, 5, 7};
1039 return 1 << (
sps->bit_depth -
offset[idx]);
1043 const ptrdiff_t dst_stride,
const ptrdiff_t src_stride,
const int c_idx,
1050 const int16_t *
coeff =
aps->chroma_coeff[idx];
1060 const ptrdiff_t dst_stride,
const ptrdiff_t luma_stride,
const int c_idx,
1061 const int width,
const int height,
const int hs,
const int vs,
const int vb_pos,
const ALFParams *alf)
1065 const int idx = c_idx - 1;
1079 const int rx = x0 >>
fc->ps.sps->ctb_log2_size_y;
1080 const int ry = y0 >>
fc->ps.sps->ctb_log2_size_y;
1081 const int ctb_size_y =
fc->ps.sps->ctb_size_y;
1084 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
1085 const int hs =
fc->ps.sps->hshift[c_idx];
1086 const int vs =
fc->ps.sps->vshift[c_idx];
1087 const int x = x0 >> hs;
1088 const int y = y0 >> vs;
1089 const int width =
FFMIN(
fc->ps.pps->width - x0, ctb_size_y) >> hs;
1090 const int height =
FFMIN(
fc->ps.pps->height - y0, ctb_size_y) >> vs;
1092 const int src_stride =
fc->frame->linesize[c_idx];
1093 uint8_t *
src =
POS(c_idx, x0, y0);
1108 if (!
pps->r->pps_loop_filter_across_tiles_enabled_flag) {
1111 edges[
RIGHT] = edges[
RIGHT] ||
pps->ctb_to_col_bd[rx] !=
pps->ctb_to_col_bd[rx + 1];
1112 edges[
BOTTOM] = edges[
BOTTOM] ||
pps->ctb_to_row_bd[ry] !=
pps->ctb_to_row_bd[ry + 1];
1115 if (!
pps->r->pps_loop_filter_across_slices_enabled_flag) {
1118 edges[
RIGHT] = edges[
RIGHT] ||
CTB(
fc->tab.slice_idx, rx, ry) !=
CTB(
fc->tab.slice_idx, rx + 1, ry);
1122 if (!
sps->r->sps_loop_filter_across_subpic_enabled_flag[subpic_idx]) {
1125 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;
1126 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;
1129 if (
sps->r->sps_virtual_boundaries_enabled_flag) {
1140 memcpy(sb_edges, edges,
sizeof(
int) *
MAX_EDGES);
1145 int *
pos[] = { &sb->
l, &sb->
t, &sb->
r, &sb->
b };
1147 for (
int vertical = 0; vertical <= 1; vertical++) {
1148 if (has_vb[vertical]) {
1150 *
pos[
c] = vb_pos[vertical];
1157 const int x0,
const int y0,
const int rx,
const int ry)
1162 const int ctu_size_y =
sps->ctb_size_y;
1164 const int has_vb[] = { vb_pos[0] > y0, vb_pos[1] > x0 };
1166 int edges[
MAX_EDGES] = { !rx, !ry, rx ==
pps->ctb_width - 1, ry ==
pps->ctb_height - 1 };
1171 for (
int by = 0; by <= has_vb[0]; by++) {
1172 for (
int bx = 0; bx <= has_vb[1]; bx++,
i++) {
1184 const int rx = x0 >>
sps->ctb_log2_size_y;
1185 const int ry = y0 >>
sps->ctb_log2_size_y;
1186 const int ps =
sps->pixel_shift;
1190 const int has_chroma = !!
sps->r->sps_chroma_format_idc;
1191 const int ctu_end = y0 +
sps->ctb_size_y;
1198 for (
int i = 0;
i < nb_sbs;
i++) {
1200 for (
int c_idx = 0; c_idx < c_end; c_idx++) {
1201 const int hs =
fc->ps.sps->hshift[c_idx];
1202 const int vs =
fc->ps.sps->vshift[c_idx];
1203 const int x = sb->
l >> hs;
1204 const int y = sb->
t >> vs;
1205 const int width = (sb->
r - sb->
l) >> hs;
1206 const int height = (sb->
b - sb->
t) >> vs;
1207 const int src_stride =
fc->frame->linesize[c_idx];
1208 uint8_t *
src =
POS(c_idx, sb->
l, sb->
t);
1214 padded_stride, src_stride, c_idx, sb_edges[
i]);
1239 const int ctb_size =
fc->ps.sps->ctb_size_y;
1240 const int width =
FFMIN(
fc->ps.pps->width - x, ctb_size);
uint8_t ptrdiff_t const uint8_t * _src
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
SwsAArch64OpImplParams params
static int BS_FUNC left(const BSCTX *bc)
Return the number of the bits left in a buffer.
#define i(width, name, range_min, range_max)
static int FUNC sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
static int FUNC ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
static int FUNC aps(CodedBitstreamContext *ctx, RWContext *rw, H266RawAPS *current, int prefix)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
void ff_vvc_decode_neighbour(VVCLocalContext *lc, const int x_ctb, const int y_ctb, const int rx, const int ry, const int rs)
int ff_vvc_get_qPy(const VVCFrameContext *fc, const int xc, const int yc)
#define BOUNDARY_LEFT_SUBPIC
#define ALF_BORDER_CHROMA
#define ALF_MAX_BLOCKS_IN_CTU
#define BOUNDARY_UPPER_SUBPIC
#define ALF_VB_POS_ABOVE_LUMA
#define ALF_VB_POS_ABOVE_CHROMA
static const uint16_t fc[]
#define MIN_TU_LOG2
MinTbLog2SizeY.
reference-counted frame API
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
static void copy_pixel(uint8_t *dst, const uint8_t *src, int pixel_shift)
static int boundary_strength(const HEVCContext *s, const MvField *curr, const MvField *neigh, const RefPicList *neigh_refPicList)
static const uint8_t betatable[52]
static void copy_vert(uint8_t *dst, const uint8_t *src, int pixel_shift, int height, ptrdiff_t stride_dst, ptrdiff_t stride_src)
static const uint8_t tctable[54]
#define BOUNDARY_UPPER_SLICE
#define BOUNDARY_LEFT_TILE
#define BOUNDARY_UPPER_TILE
#define EDGE_EMU_BUFFER_STRIDE
#define BOUNDARY_LEFT_SLICE
static int shift(int a, int b)
static const uint16_t mask[17]
#define FFSWAP(type, a, b)
#define FF_ARRAY_ELEMS(a)
uint8_t ctb_flag[3]
alf_ctb_flag[]
uint8_t alf_ctb_filter_alt_idx[2]
alf_ctb_filter_alt_idx[]
uint8_t ctb_filt_set_idx_y
AlfCtbFiltSetIdxY.
uint8_t ctb_cc_idc[2]
alf_ctb_cc_cb_idc, alf_ctb_cc_cr_idc
enum PredMode pred_mode
PredMode.
int bdpcm_flag[VVC_MAX_SAMPLE_ARRAYS]
BdpcmFlag.
uint8_t pps_loop_filter_across_tiles_enabled_flag
uint8_t pps_loop_filter_across_slices_enabled_flag
uint16_t sps_subpic_ctu_top_left_x[VVC_MAX_SLICES]
uint16_t sps_subpic_ctu_top_left_y[VVC_MAX_SLICES]
uint8_t sps_virtual_boundaries_enabled_flag
uint16_t sps_subpic_height_minus1[VVC_MAX_SLICES]
uint16_t sps_subpic_width_minus1[VVC_MAX_SLICES]
uint16_t sps_num_subpics_minus1
uint8_t sps_loop_filter_across_subpic_enabled_flag[VVC_MAX_SLICES]
int8_t ref_idx[2]
refIdxL0, refIdxL1
uint8_t ciip_flag
ciip_flag
int16_t x
horizontal component of motion vector
int16_t y
vertical component of motion vector
uint8_t inter_affine_flag
uint8_t merge_subblock_flag
VVCRefPic refs[VVC_MAX_REF_ENTRIES]
int16_t offset_val[3][5]
SaoOffsetVal.
uint8_t band_position[3]
sao_band_position
int eo_class[3]
sao_eo_class
uint8_t type_idx[3]
sao_type_idx
struct VVCFrameContext::@062157055061031125261364230274065254203010127363 tab
struct VVCLocalContext::@341344066320375062105147172263124117020342060326::@055222342063040312177217323172174124065003301256 alf
only accessed in ff_vvc_alf_filter() during the alf processing stage
struct VVCLocalContext::@341344066320375062105147172263124117020342060326::@103125161133210147111054051001007356327371002074 sao
only accessed in ff_vvc_sao_filter() during the sao processing stage
uint8_t buffer_luma[(MAX_CTU_SIZE+2 *ALF_PADDING_SIZE) *EDGE_EMU_BUFFER_STRIDE *2]
int32_t gradient_tmp[ALF_GRADIENT_SIZE *ALF_GRADIENT_SIZE *ALF_NUM_DIR]
int16_t clip_tmp[ALF_MAX_FILTER_SIZE]
uint8_t buffer_chroma[(MAX_CTU_SIZE+2 *ALF_PADDING_SIZE) *EDGE_EMU_BUFFER_STRIDE *2]
uint8_t buffer[(MAX_CTU_SIZE+2 *SAO_PADDING_SIZE) *EDGE_EMU_BUFFER_STRIDE *2]
int16_t coeff_tmp[ALF_MAX_FILTER_SIZE]
const H266RawSliceHeader * r
RefStruct reference.
static const struct twinvq_data tab
static double cb(void *priv, double x, double y)
static const double coeff[2][5]
const int16_t ff_vvc_alf_fix_filt_coeff[64][12]
const uint8_t ff_vvc_alf_class_to_filt_map[16][25]
const uint8_t ff_vvc_alf_aps_class_to_filt_map[25]
static void alf_extend_vert(uint8_t *_dst, const uint8_t *_src, const int pixel_shift, const int width, const int height, ptrdiff_t stride)
static void alf_copy_border(uint8_t *dst, const uint8_t *src, const int pixel_shift, int width, const int height, const ptrdiff_t dst_stride, const ptrdiff_t src_stride)
static void max_filter_length_chroma(const VVCFrameContext *fc, const int qx, const int qy, const int vertical, const int horizontal_ctu_edge, const int bs, uint8_t *max_len_p, uint8_t *max_len_q)
static int get_qp_y(const VVCFrameContext *fc, const uint8_t *src, const int x, const int y, const int vertical)
void ff_vvc_lmcs_filter(const VVCLocalContext *lc, const int x, const int y)
lmcs filter for the CTU
static void max_filter_length(const VVCFrameContext *fc, const int qx, const int qy, 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)
void ff_vvc_deblock_horizontal(const VVCLocalContext *lc, const int x0, const int y0, const int rs)
horizontal deblock filter for the CTU
static void alf_fill_border_h(uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, const ptrdiff_t src_stride, const uint8_t *border, const int width, const int border_pixels, const int ps, const int edge)
static void alf_init_subblock(VVCRect *sb, int sb_edges[MAX_EDGES], const VVCRect *b, const int edges[MAX_EDGES])
static void alf_copy_ctb_to_hv(VVCFrameContext *fc, const uint8_t *src, const ptrdiff_t src_stride, const int x, const int y, const int width, const int height, const int rx, const int ry, const int c_idx)
static void alf_get_subblocks(const VVCLocalContext *lc, VVCRect sbs[MAX_VBBS], int sb_edges[MAX_VBBS][MAX_EDGES], int *nb_sbs, const int x0, const int y0, const int rx, const int ry)
static int is_virtual_boundary(const VVCFrameContext *fc, const int pos, const int vertical)
static void alf_filter_chroma(VVCLocalContext *lc, uint8_t *dst, const uint8_t *src, const ptrdiff_t dst_stride, const ptrdiff_t src_stride, const int c_idx, const int width, const int height, const int vb_pos, const ALFParams *alf)
static void alf_get_subblock(VVCRect *sb, int edges[MAX_EDGES], const int bx, const int by, const int vb_pos[2], const int has_vb[2])
void ff_vvc_deblock_vertical(const VVCLocalContext *lc, const int x0, const int y0, const int rs)
vertical deblock filter for the CTU
static void alf_filter_luma(VVCLocalContext *lc, uint8_t *dst, const uint8_t *src, const ptrdiff_t dst_stride, const ptrdiff_t src_stride, const int x0, const int y0, const int width, const int height, const int _vb_pos, const ALFParams *alf)
static void copy_ctb(uint8_t *dst, const uint8_t *src, const int width, const int height, const ptrdiff_t dst_stride, const ptrdiff_t src_stride)
static void sao_copy_ctb_to_hv(VVCLocalContext *lc, const int rx, const int ry, const int top)
static void copy_ctb_to_hv(VVCFrameContext *fc, const uint8_t *src, const ptrdiff_t src_stride, const int x, const int y, const int width, const int height, const int c_idx, const int rx, const int ry, const int top)
static av_always_inline int deblock_bs(const VVCLocalContext *lc, const int x_p, const int y_p, const int x_q, const int y_q, const CodingUnit *cu, const TransformUnit *tu, const RefPicList *rpl_p, const int c_idx, const int off_to_cb, const uint8_t has_sub_block)
static void alf_get_coeff_and_clip(VVCLocalContext *lc, int16_t *coeff, int16_t *clip, const uint8_t *src, ptrdiff_t src_stride, int width, int height, int vb_pos, const ALFParams *alf)
static int get_virtual_boundary(const VVCFrameContext *fc, const int ctu_pos, const int vertical)
static void sao_restore_vb(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, const int width, const int height, const int vb_pos, const int ps, const int vertical)
static int get_qPc(const VVCFrameContext *fc, const int x0, const int y0, const int chroma)
static void vvc_deblock(const VVCLocalContext *lc, int x0, int y0, const int rs, const int vertical)
void ff_vvc_alf_filter(VVCLocalContext *lc, const int x0, const int y0)
alf filter for the CTU
static void vvc_deblock_bs_luma(const VVCLocalContext *lc, const int x0, const int y0, const int width, const int height, const CodingUnit *cu, const TransformUnit *tu, int rs, const int vertical)
void ff_vvc_sao_copy_ctb_to_hv(VVCLocalContext *lc, const int rx, const int ry, const int last_row)
static void alf_filter_cc(VVCLocalContext *lc, uint8_t *dst, const uint8_t *luma, const ptrdiff_t dst_stride, const ptrdiff_t luma_stride, const int c_idx, const int width, const int height, const int hs, const int vs, const int vb_pos, const ALFParams *alf)
static int get_qp(const VVCFrameContext *fc, const uint8_t *src, const int x, const int y, const int c_idx, const int vertical)
static void alf_fill_border_v(uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, const uint8_t *border, const int border_pixels, const int height, const int pixel_shift, const int *edges, const int edge)
static void sao_copy_hor(uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, const ptrdiff_t src_stride, const int width, const int edges[4], const int ps)
void ff_vvc_alf_copy_ctu_to_hv(VVCLocalContext *lc, const int x0, const int y0)
#define TAB_MAX_LEN(t, x, y)
static void max_filter_length_luma(const VVCFrameContext *fc, const int qx, const int qy, const int vertical, uint8_t *max_len_p, uint8_t *max_len_q)
static void vvc_deblock_subblock_bs(const VVCLocalContext *lc, const int cb, int x0, int y0, int width, int height, const int vertical)
static int get_qp_c(const VVCFrameContext *fc, const int x, const int y, const int c_idx, const int vertical)
static int alf_clip_from_idx(const VVCFrameContext *fc, const int idx)
void ff_vvc_deblock_bs(VVCLocalContext *lc, const int rx, const int ry, const int rs)
derive boundary strength for the CTU
static int deblock_is_boundary(const VVCLocalContext *lc, const int boundary, const int pos, const int rs, const int vertical)
static void sao_extends_edges(uint8_t *dst, const ptrdiff_t dst_stride, const uint8_t *src, const ptrdiff_t src_stride, const int width, const int height, const VVCFrameContext *fc, const int x0, const int y0, const int rx, const int ry, const int edges[4], const int c_idx)
static void alf_get_edges(const VVCLocalContext *lc, int edges[MAX_EDGES], const int rx, const int ry)
static void vvc_deblock_bs_chroma(const VVCLocalContext *lc, const int x0, const int y0, const int width, const int height, const CodingUnit *cu, const TransformUnit *tu, const int rs, const int vertical)
static void alf_prepare_buffer(VVCFrameContext *fc, uint8_t *_dst, const uint8_t *_src, const int x, const int y, const int rx, const int ry, const int width, const int height, const ptrdiff_t dst_stride, const ptrdiff_t src_stride, const int c_idx, const int *edges)
void ff_vvc_sao_filter(VVCLocalContext *lc, int x0, int y0)
sao filter for the CTU
static void sao_get_edges(uint8_t vert_edge[2], uint8_t horiz_edge[2], uint8_t diag_edge[4], int *restore, const VVCLocalContext *lc, const int edges[4], const int rx, const int ry)
static void derive_max_filter_length_luma(const VVCFrameContext *fc, const int qx, const int qy, const int size_q, const int has_subblock, const int vertical, uint8_t *max_len_p, uint8_t *max_len_q)
static void alf_extend_horz(uint8_t *dst, const uint8_t *src, const int pixel_shift, int width, const int height, const ptrdiff_t stride)
void(* deblock_bs_fn)(const VVCLocalContext *lc, const int x0, const int y0, const int width, const int height, const int rs, const int vertical)
static int sao_can_cross_slices(const VVCFrameContext *fc, const int rx, const int ry, const int dx, const int dy)
#define ALF_NUM_COEFF_LUMA
#define ALF_NUM_FILTERS_LUMA
#define ALF_NUM_COEFF_CHROMA
const RefPicList * ff_vvc_get_ref_list(const VVCFrameContext *fc, const VVCFrame *ref, int x0, int y0)