28#define IS_SAME_MV(a, b) (AV_RN64A(a) == AV_RN64A(b))
33 const uint8_t plevel =
fc->ps.sps->log2_parallel_merge_level;
35 return xN >> plevel == xP >> plevel &&
36 yN >> plevel == yP >> plevel;
44 for (
int i = 0;
i < 2;
i++) {
49 if (!same_ref_idx || !same_mv)
59 int mv[2] = {motion->
x, motion->
y};
60 for (
int i = 0;
i < 2;
i++) {
61 const int s =
mv[
i] >> 17;
63 const int mask = (-1 * (1 <<
f)) >> 1;
64 const int round = (1 <<
f) >> 2;
77 tx = (0x4000 + (
abs(td) >> 1)) / td;
80 (scale_factor *
src->x < 0)) >> 8, 17);
82 (scale_factor *
src->y < 0)) >> 8, 17);
89 const RefPicList *refPicList_col,
int listCol,
int refidxCol)
91 int cur_lt = refPicList[
X].
refs[refIdxLx].
is_lt;
92 int col_lt = refPicList_col[listCol].
refs[refidxCol].
is_lt;
93 int col_poc_diff, cur_poc_diff;
95 if (cur_lt != col_lt) {
101 col_poc_diff = colPic - refPicList_col[listCol].
refs[refidxCol].
poc;
102 cur_poc_diff = poc - refPicList[
X].
refs[refIdxLx].
poc;
105 if (cur_lt || col_poc_diff == cur_poc_diff) {
114#define CHECK_MVSET(l) \
115 check_mvset(mvLXCol, temp_col.mv + l, \
116 colPic, fc->ps.ph.poc, \
117 refPicList, X, refIdxLx, \
118 refPicList_col, L ## l, temp_col.ref_idx[l])
123 int check_diffpicount = 0;
127 for (j = 0; j < 2; j++) {
135 return !check_diffpicount;
140 int refIdxLx,
Mv *mvLXCol,
int X,
141 int colPic,
const RefPicList *refPicList_col,
int sb_flag)
186#define TAB_MVF(x, y) \
187 tab_mvf[((y) >> MIN_PU_LOG2) * min_pu_width + ((x) >> MIN_PU_LOG2)]
189#define TAB_MVF_PU(v) \
190 TAB_MVF(x ## v, y ## v)
192#define TAB_CP_MV(lx, x, y) \
193 fc->tab.cp_mv[lx][((((y) >> min_cb_log2_size) * min_cb_width + ((x) >> min_cb_log2_size)) ) * MAX_CONTROL_POINTS]
196#define DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag) \
197 derive_temporal_colocated_mvs(lc, temp_col, \
198 refIdxLx, mvLXCol, X, colPic, \
199 ff_vvc_get_ref_list(fc, ref, x, y), sb_flag)
203 const int refIdxLx,
Mv *mvLXCol,
const int X,
int check_center,
int sb_flag)
210 int x, y, x_end, y_end, colPic, availableFlagLXCol = 0;
211 int min_pu_width =
fc->ps.pps->min_pu_width;
217 memset(mvLXCol, 0,
sizeof(*mvLXCol));
224 tab_mvf =
ref->tab_dmvr_mvf;
231 x_end =
pps->subpic_x[subpic_idx] +
pps->subpic_width[subpic_idx];
232 y_end =
pps->subpic_y[subpic_idx] +
pps->subpic_height[subpic_idx];
235 (cu->
y0 >>
sps->ctb_log2_size_y) == (y >>
sps->ctb_log2_size_y) &&
236 x < x_end && y < y_end) {
244 if (tab_mvf && !availableFlagLXCol) {
253 return availableFlagLXCol;
260 const int min_pu_width =
fc->ps.pps->min_pu_width;
262 for (
int dy = 0; dy <
h; dy += min_pu_size) {
263 for (
int dx = 0; dx <
w; dx += min_pu_size) {
264 const int x = x0 + dx;
265 const int y = y0 + dy;
276 const int min_pu_width =
fc->ps.pps->min_pu_width;
278 for (
int dy = 0; dy < cu->
cb_height; dy += min_pu_size) {
279 for (
int dx = 0; dx < cu->
cb_width; dx += min_pu_size) {
280 const int x = cu->
x0 + dx;
281 const int y = cu->
y0 + dy;
285 mv->ciip_flag = ciip_flag;
294 const Mv* cp_mv = &
mi->mv[lx][0];
325 const int a = 4 * (2048 + sp->
d_hor_x);
327 const int c = 4 * (2048 + sp->
d_ver_y);
329 if (pred_flag ==
PF_BI) {
334 const int bx_wx4 = ((max_w4 - min_w4) >> 11) + 9;
335 const int bx_hx4 = ((max_h4 - min_h4) >> 11) + 9;
336 return bx_wx4 * bx_hx4 > 225;
338 const int bx_wxh = (
FFABS(
a) >> 11) + 9;
339 const int bx_hxh = (
FFABS(d) >> 11) + 9;
340 const int bx_wxv = (
FFABS(
b) >> 11) + 9;
341 const int bx_hxv = (
FFABS(
c) >> 11) + 9;
342 if (bx_wxh * bx_hxh <= 165 && bx_wxv * bx_hxv <= 165)
349 const int cb_width,
const int cb_height,
const int lx)
351 const int log2_cbw =
av_log2(cb_width);
352 const int log2_cbh =
av_log2(cb_height);
353 const Mv* cp_mv =
mi->mv[lx];
354 const int num_cp_mv =
mi->motion_model_idc + 1;
357 if (num_cp_mv == 3) {
375 const int dmv_limit = 1 << 5;
395 const int log2_min_cb_size =
fc->ps.sps->min_cb_log2_size_y;
396 const int min_cb_size =
fc->ps.sps->min_cb_size_y;
397 const int min_cb_width =
fc->ps.pps->min_cb_width;
398 const int num_cp_mv =
mi->motion_model_idc + 1;
400 for (
int dy = 0; dy < cu->
cb_height; dy += min_cb_size) {
401 for (
int dx = 0; dx < cu->
cb_width; dx += min_cb_size) {
402 const int x_cb = (cu->
x0 + dx) >> log2_min_cb_size;
403 const int y_cb = (cu->
y0 + dy) >> log2_min_cb_size;
406 memcpy(&
fc->tab.cp_mv[lx][
offset],
mi->mv[lx],
sizeof(
Mv) * num_cp_mv);
424 for (
int i = 0;
i < 2;
i++) {
426 if (
mi->pred_flag &
mask) {
434 for (
int sby = 0; sby <
mi->num_sb_y; sby++) {
435 for (
int sbx = 0; sbx <
mi->num_sb_x; sbx++) {
436 const int x0 = cu->
x0 + sbx * sbw;
437 const int y0 = cu->
y0 + sby * sbh;
438 for (
int i = 0;
i < 2;
i++) {
440 if (
mi->pred_flag &
mask) {
464 const int is_flip = angle_idx >= 13 &&angle_idx <= 27;
465 const int shift_hor = (angle_idx % 16 == 8 || (angle_idx % 16 && cu->
cb_height >= cu->
cb_width)) ? 0 : 1;
466 const int sign = angle_idx < 16 ? 1 : -1;
467 const int block_size = 4;
468 int offset_x = (-cu->
cb_width) >> 1;
472 offset_y += sign * ((distance_idx * cu->
cb_height) >> 3);
474 offset_x += sign * ((distance_idx * cu->
cb_width) >> 3);
476 for (
int y = 0; y < cu->
cb_height; y += block_size) {
477 for (
int x = 0; x < cu->
cb_width; x += block_size) {
478 const int motion_idx = (((x + offset_x) * (1 << 1)) + 5) * displacement_x +
479 (((y + offset_y) * (1 << 1)) + 5) * displacement_y;
480 const int s_type =
FFABS(motion_idx) < 32 ? 2 : (motion_idx <= 0 ? (1 - is_flip) : is_flip);
482 const int x0 = cu->
x0 + x;
483 const int y0 = cu->
y0 + y;
487 else if (s_type == 1 || (s_type == 2 && pred_flag !=
PF_BI))
495 mvf.
mv[lx] = mv1->
mv[lx];
517 for (
int i = 0;
i < 2;
i++) {
555 const int x = x0 >>
sps->min_cb_log2_size_y;
556 const int y = y0 >>
sps->min_cb_log2_size_y;
557 const int min_cb_width =
fc->ps.pps->min_cb_width;
567 int cand_bottom_left;
570 cand_bottom_left = 0;
572 const int max_y =
FFMIN(
fc->ps.pps->height, ((cu->
y0 >>
sps->ctb_log2_size_y) + 1) <<
sps->ctb_log2_size_y);
574 cand_bottom_left = 0;
578 return cand_bottom_left;
585 const int x0 = cu->
x0;
586 const int y0 = cu->
y0;
592 { x0 - 1, y0 + cb_height, !a0_available },
593 { x0 - 1, y0 + cb_height - 1, !na->
cand_left },
596 { x0 + cb_width - 1, y0 - 1, !na->
cand_up },
601 memcpy(
ctx->neighbours, neighbours,
sizeof(neighbours));
628 const int min_pu_width =
fc->ps.pps->min_pu_width;
632 n->
available = !
sps->r->sps_entropy_coding_sync_enabled_flag || ((n->
x >>
sps->ctb_log2_size_y) <= (cu->
x0 >>
sps->ctb_log2_size_y));
643 const int min_pu_width =
fc->ps.pps->min_pu_width;
659#define MV_MERGE_FROM_NB(nb) mv_merge_from_nb(&nctx, nb)
682 cand_list[num_cands] = *cand;
683 if (merge_idx == num_cands)
688 if (num_cands != 4) {
692 cand_list[num_cands] = *cand;
693 if (merge_idx == num_cands)
698 *nb_merge_cand = num_cands;
707 memset(cand, 0,
sizeof(*cand));
712 cand->
pred_flag = available_l0 + (available_l1 << 1);
723 for (
int i = 1;
i <= ep->
num_hmvp && (*num_cands <
sps->max_num_merge_cand - 1);
i++) {
727 cand_list[*num_cands] = *
h;
728 if (merge_idx == *num_cands)
740 const int num_ref_rists = is_b ? 2 : 1;
741 const MvField* p0 = cand_list + 0;
742 const MvField* p1 = cand_list + 1;
743 MvField* cand = cand_list + num_cands;
746 for (
int i = 0;
i < num_ref_rists;
i++) {
777 MvField *cand_list,
int num_cands)
781 const int num_ref_idx =
IS_P(rsh) ?
785 while (num_cands < sps->max_num_merge_cand) {
786 MvField *cand = cand_list + num_cands;
791 cand->
ref_idx[0] = zero_idx < num_ref_idx ? zero_idx : 0;
792 cand->
ref_idx[1] = zero_idx < num_ref_idx ? zero_idx : 0;
795 if (merge_idx == num_cands)
811 if (merge_idx == num_cands)
820 if (merge_idx == num_cands)
836 *
mv = cand_list[merge_idx];
838 mv->ciip_flag = ciip_flag;
847 const int idx[] = { merge_gpm_idx[0], merge_gpm_idx[1] + (merge_gpm_idx[1] >= merge_gpm_idx[0]) };
851 memset(
mv, 0, 2 *
sizeof(*
mv));
852 for (
int i = 0;
i < 2;
i++) {
862 mv[
i].mv[lx] = cand->
mv[lx];
869 const int x_nb,
int y_nb,
const int nbw,
const int nbh,
const int lx,
870 Mv *cps,
int num_cps)
874 const int x0 = cu->
x0;
875 const int y0 = cu->
y0;
879 const int min_cb_log2_size =
fc->ps.sps->min_cb_log2_size_y;
880 const int min_cb_width =
fc->ps.pps->min_cb_width;
882 const int log2_nbw =
ff_log2(nbw);
883 const int log2_nbh =
ff_log2(nbh);
884 const int is_ctb_boundary = !((y_nb + nbh) %
fc->ps.sps->ctb_size_y) && (y_nb + nbh == y0);
886 int mv_scale_hor, mv_scale_ver, d_hor_x, d_ver_x, d_hor_y, d_ver_y, motion_model_idc_nb;
887 if (is_ctb_boundary) {
888 const int min_pu_width =
fc->ps.pps->min_pu_width;
889 l = &
TAB_MVF(x_nb, y_nb + nbh - 1).mv[lx];
890 r = &
TAB_MVF(x_nb + nbw - 1, y_nb + nbh - 1).mv[lx];
892 const int x = x_nb >> min_cb_log2_size;
893 const int y = y_nb >> min_cb_log2_size;
899 mv_scale_hor = l->
x * (1 << 7);
900 mv_scale_ver = l->
y * (1 << 7);
901 d_hor_x = (
r->x - l->
x) * (1 << (7 - log2_nbw));
902 d_ver_x = (
r->y - l->
y) * (1 << (7 - log2_nbw));
904 const Mv* lb = &
TAB_CP_MV(lx, x_nb, y_nb + nbh - 1) + 2;
905 d_hor_y = (lb->
x - l->
x) * (1 << (7 - log2_nbh));
906 d_ver_y = (lb->
y - l->
y) * (1 << (7 - log2_nbh));
912 if (is_ctb_boundary) {
915 cps[0].
x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 - y_nb);
916 cps[0].
y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 - y_nb);
917 cps[1].
x = mv_scale_hor + d_hor_x * (x0 + cb_width - x_nb) + d_hor_y * (y0 - y_nb);
918 cps[1].
y = mv_scale_ver + d_ver_x * (x0 + cb_width - x_nb) + d_ver_y * (y0 - y_nb);
920 cps[2].
x = mv_scale_hor + d_hor_x * (x0 - x_nb) + d_hor_y * (y0 + cb_height - y_nb);
921 cps[2].
y = mv_scale_ver + d_ver_x * (x0 - x_nb) + d_ver_y * (y0 + cb_height - y_nb);
923 for (
int i = 0;
i < num_cps;
i++) {
932 const int log2_min_cb_size =
fc->ps.sps->min_cb_log2_size_y;
933 const int min_cb_width =
fc->ps.pps->min_cb_width;
934 const int x = x_nb >> log2_min_cb_size;
935 const int y = y_nb >> log2_min_cb_size;
936 const int motion_model_idc =
SAMPLE_CTB(
fc->tab.mmi, x, y);
937 if (motion_model_idc) {
943 return motion_model_idc;
950 int x, y,
w,
h, motion_model_idc;
953 if (motion_model_idc) {
954 const int min_pu_width =
fc->ps.pps->min_pu_width;
960 for (
int i = 0;
i < 2;
i++) {
962 if (
mi->pred_flag &
mask) {
967 mi->motion_model_idc = motion_model_idc;
969 return motion_model_idc;
975 for (
int i = 0;
i < num_nbs;
i++) {
982#define AFFINE_MERGE_FROM_NBS(nbs) affine_merge_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), mi)
989 const int min_pu_width =
fc->ps.pps->min_pu_width;
990 for (
int i = 0;
i < num_neighbour;
i++) {
999#define DERIVE_CORNER_MV(nbs) derive_corner_mvf(nctx, nbs, FF_ARRAY_ELEMS(nbs))
1006 if (!(
B->pred_flag &
mask))
1008 if (
A->ref_idx[lx] !=
B->ref_idx[lx])
1011 if (!(
C->pred_flag &
mask))
1013 if (
A->ref_idx[lx] !=
C->ref_idx[lx])
1020 const int x_ctb,
const int y_ctb,
const Mv* temp_mv,
int *x,
int *y)
1024 const int ctb_log2_size =
fc->ps.sps->ctb_log2_size_y;
1026 const int x_end =
pps->subpic_x[subpic_idx] +
pps->subpic_width[subpic_idx];
1027 const int y_end =
pps->subpic_y[subpic_idx] +
pps->subpic_height[subpic_idx];
1029 *x =
av_clip(*x + temp_mv->
x, x_ctb,
FFMIN(x_end - 1, x_ctb + (1 << ctb_log2_size) + 3)) & ~7;
1030 *y =
av_clip(*y + temp_mv->
y, y_ctb,
FFMIN(y_end - 1, y_ctb + (1 << ctb_log2_size) - 1)) & ~7;
1034 const int x_ctb,
const int y_ctb,
const Mv *temp_mv,
1035 int x,
int y, uint8_t *pred_flag,
Mv *
mv)
1039 const int refIdxLx = 0;
1042 const int min_pu_width =
fc->ps.pps->min_pu_width;
1045 int colPic =
ref->poc;
1062 const int x_ctb,
const int y_ctb,
MvField *ctr_mvf,
Mv *temp_mv)
1073 memset(temp_mv, 0,
sizeof(*temp_mv));
1076 memset(ctr_mvf, 0,
sizeof(*ctr_mvf));
1084 *temp_mv =
a1->mv[0];
1086 *temp_mv =
a1->mv[1];
1103 const int ctb_log2_size =
sps->ctb_log2_size_y;
1104 const int x0 = cu->
x0;
1105 const int y0 = cu->
y0;
1110 const int x_ctb = (x0 >> ctb_log2_size) << ctb_log2_size;
1111 const int y_ctb = (y0 >> ctb_log2_size) << ctb_log2_size;
1114 if (!
ph->r->ph_temporal_mvp_enabled_flag ||
1115 !
sps->r->sps_sbtmvp_enabled_flag ||
1127 for (
int sby = 0; sby <
mi->num_sb_y; sby++) {
1128 for (
int sbx = 0; sbx <
mi->num_sb_x; sbx++) {
1129 int x = x0 + sbx * sbw;
1130 int y = y0 + sby * sbh;
1134 memcpy(mvf.
mv, ctr_mvf.
mv,
sizeof(mvf.
mv));
1146 if (c0 &&
c1 &&
c2) {
1148 for (
int i = 0;
i < 2;
i++) {
1153 mi->mv[
i][0] = c0->
mv[
i];
1154 mi->mv[
i][1] =
c1->mv[
i];
1155 mi->mv[
i][2] =
c2->mv[
i];
1158 if (
mi->pred_flag) {
1170 if (c0 &&
c1 && c3) {
1172 for (
int i = 0;
i < 2;
i++) {
1177 mi->mv[
i][0] = c0->
mv[
i];
1178 mi->mv[
i][1] =
c1->mv[
i];
1184 if (
mi->pred_flag) {
1195 if (c0 &&
c2 && c3) {
1197 for (
int i = 0;
i < 2;
i++) {
1202 mi->mv[
i][0] = c0->
mv[
i];
1206 mi->mv[
i][2] =
c2->mv[
i];
1209 if (
mi->pred_flag) {
1220 if (
c1 &&
c2 && c3) {
1222 for (
int i = 0;
i < 2;
i++) {
1226 mi->ref_idx[
i] =
c1->ref_idx[
i];
1230 mi->mv[
i][1] =
c1->mv[
i];
1231 mi->mv[
i][2] =
c2->mv[
i];
1234 if (
mi->pred_flag) {
1235 mi->bcw_idx =
mi->pred_flag ==
PF_BI ?
c1->bcw_idx : 0;
1247 for (
int i = 0;
i < 2;
i++) {
1252 mi->mv[
i][0] = c0->
mv[
i];
1253 mi->mv[
i][1] =
c1->mv[
i];
1256 if (
mi->pred_flag) {
1271 for (
int i = 0;
i < 2;
i++) {
1276 mi->mv[
i][0] = c0->
mv[
i];
1283 if (
mi->pred_flag) {
1297 memset(
mi, 0,
sizeof(*
mi));
1319 if (
fc->ps.sps->r->sps_6param_affine_enabled_flag) {
1323 if (merge_subblock_idx == num_cands)
1328 memset(&corner3, 0,
sizeof(corner3));
1329 if (
fc->ps.ph.r->ph_temporal_mvp_enabled_flag){
1334 corner3.
pred_flag = available_l0 + (available_l1 << 1);
1341 if (merge_subblock_idx == num_cands)
1348 if (merge_subblock_idx == num_cands)
1355 if (merge_subblock_idx == num_cands)
1363 if (merge_subblock_idx == num_cands)
1369 if (merge_subblock_idx == num_cands)
1389 if (merge_subblock_idx == num_cands)
1398 if (
sps->r->sps_affine_enabled_flag) {
1403 if (merge_subblock_idx == num_cands)
1410 if (merge_subblock_idx == num_cands)
1434 const int lx,
const int8_t *ref_idx,
Mv *
mv)
1438 const int min_pu_width =
fc->ps.pps->min_pu_width;
1442 const int poc = rpl[lx].
refs[ref_idx[lx]].
poc;
1461 const int x_cand,
const int y_cand,
const int lx,
const int8_t *ref_idx,
1462 Mv *cps,
const int num_cp)
1465 int x_nb, y_nb, nbw, nbh, motion_model_idc, available = 0;
1468 if (motion_model_idc) {
1469 const int min_pu_width =
fc->ps.pps->min_pu_width;
1474 const int poc = rpl[lx].
refs[ref_idx[lx]].
poc;
1493 const NeighbourIdx *nbs,
const int num_nbs,
const int lx,
const int8_t *ref_idx,
const int amvr_shift,
1494 Mv *cps,
const int num_cps)
1499 for (
int i = 0;
i < num_nbs;
i++) {
1507 for (
int c = 0;
c < num_cps;
c++)
1517#define AFFINE_MVP_FROM_NBS(nbs) \
1518 mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, cps, num_cp) \
1520#define MVP_FROM_NBS(nbs) \
1521 mvp_from_nbs(&nctx, nbs, FF_ARRAY_ELEMS(nbs), lx, ref_idx, amvr_shift, mv, 1) \
1524 const int mvp_lx_flag,
const int lx,
const int8_t* ref_idx,
const int amvr_shift,
1525 Mv*
mv,
int *nb_merge_cand)
1530 int available_a, num_cands = 0;
1537 if (mvp_lx_flag == num_cands)
1544 if (mvp_lx_flag == num_cands)
1549 *nb_merge_cand = num_cands;
1554 const int mvp_lx_flag,
const int lx,
const int8_t *ref_idx,
const int amvr_shift,
1555 Mv*
mv,
int *num_cands)
1558 if (mvp_lx_flag == *num_cands) {
1569 const int mvp_lx_flag,
const int lx,
const int8_t ref_idx,
const int amvr_shift,
1570 Mv *
mv,
int num_cands)
1574 const int poc = rpl[lx].
refs[ref_idx].
poc;
1580 for (
int j = 0; j < 2; j++) {
1581 const int ly = (j ? !lx : lx);
1583 if ((
h->pred_flag &
mask) && poc == rpl[ly].
refs[
h->ref_idx[ly]].
poc) {
1584 if (mvp_lx_flag == num_cands) {
1598 const int8_t *ref_idx,
const int amvr_shift,
Mv *
mv)
1611 memset(
mv, 0,
sizeof(*
mv));
1622 mvp(lc, mvp_lx_flag[
L0],
L0,
mi->ref_idx, amvr_shift, &
mi->mv[
L0][0]);
1624 mvp(lc, mvp_lx_flag[
L1],
L1,
mi->ref_idx, amvr_shift, &
mi->mv[
L1][0]);
1631 const int min_pu_width =
fc->ps.pps->min_pu_width;
1649 if (num_cands > merge_idx)
1654 if (!num_cands || !
IS_SAME_MV(&cand_list[0], mvf->
mv)) {
1655 cand_list[num_cands++] = mvf->
mv[
L0];
1656 if (num_cands > merge_idx)
1661 *nb_merge_cand = num_cands;
1666 const int merge_idx,
Mv *cand_list,
int *nb_merge_cand)
1671 int num_cands = *nb_merge_cand;
1674 int same_motion = 0;
1676 for (
int j = 0; j < *nb_merge_cand; j++) {
1677 same_motion = is_gt4by4 &&
i == 1 &&
IS_SAME_MV(&mvf->
mv[
L0], &cand_list[j]);
1682 cand_list[num_cands++] = mvf->
mv[
L0];
1683 if (num_cands > merge_idx)
1688 *nb_merge_cand = num_cands;
1693#define IBC_SHIFT(v) ((v) >= (1 << (MV_BITS - 1)) ? ((v) - (1 << MV_BITS)) : (v))
1712 *
mv = cand_list[merge_idx];
1717 memset(
mv, 0,
sizeof(*
mv));
1727 if (
sps->ctb_size_y < ((cu->
y0 + (bv->
y >> 4)) & (
sps->ctb_size_y - 1)) + cu->
cb_height) {
1751 const NeighbourIdx *neighbour,
const int num_neighbour,
1752 const int lx,
const int8_t ref_idx,
const int amvr_shift,
Mv *cp)
1757 const int min_pu_width =
fc->ps.pps->min_pu_width;
1761 for (
int i = 0;
i < num_neighbour;
i++) {
1766 const int poc = rpl[lx].
refs[ref_idx].
poc;
1787#define AFFINE_MVP_CONSTRUCTED_CP(cands, cp) \
1788 affine_mvp_constructed_cp(nctx, cands, FF_ARRAY_ELEMS(cands), lx, ref_idx, \
1793 const int lx,
const int8_t ref_idx,
const int amvr_shift,
1794 Mv *cps,
int *available)
1803 return available[0] && available[1];
1809 const Mv mv = cps[idx];
1810 for (
int j = 0; j < num_cp; j++)
1816 const int mvp_lx_flag,
const int lx,
const int8_t *ref_idx,
const int amvr_shift,
1821 const int num_cp = motion_model_idc + 1;
1829 if (mvp_lx_flag == num_cands)
1835 if (mvp_lx_flag == num_cands)
1843 if (mvp_lx_flag == num_cands)
1850 for (
int i = 2;
i >= 0;
i--) {
1852 if (mvp_lx_flag == num_cands) {
1860 if (mvp_lx_flag == num_cands) {
1862 for (
int i = 1;
i < num_cp;
i++)
1870 memset(cps, 0, num_cp *
sizeof(
Mv));
1891 const int offset = 1 << (rshift - 1);
1892 mv->x = ((
mv->x +
offset - (
mv->x >= 0)) >> rshift) * (1 << lshift);
1893 mv->y = ((
mv->y +
offset - (
mv->y >= 0)) >> rshift) * (1 << lshift);
1895 mv->x =
mv->x * (1 << lshift);
1896 mv->y =
mv->y * (1 << lshift);
1902 mv->x =
av_clip(
mv->x, -(1 << 17), (1 << 17) - 1);
1903 mv->y =
av_clip(
mv->y, -(1 << 17), (1 << 17) - 1);
1909 const uint8_t plevel =
fc->ps.sps->log2_parallel_merge_level;
1911 return x0_br >> plevel > x0 >> plevel &&
1912 y0_br >> plevel > y0 >> plevel;
1919 for (
i = 0;
i < *num_hmvp;
i++) {
1930 memmove(hmvp +
i, hmvp +
i + 1, (*num_hmvp -
i) *
sizeof(
MvField));
1931 hmvp[(*num_hmvp)++] = *mvf;
1945 const int min_pu_width =
fc->ps.pps->min_pu_width;
1962 const int min_pu_width =
fc->ps.pps->min_pu_width;
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
SwsAArch64OpImplParams params
#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)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
void ff_vvc_set_neighbour_available(VVCLocalContext *lc, const int x0, const int y0, const int w, const int h)
#define AFFINE_MIN_BLOCK_SIZE
#define MAX_NUM_HMVP_CANDS
#define MAX_CONTROL_POINTS
static const uint16_t fc[]
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static int temporal_luma_motion_vector(const HEVCContext *s, const HEVCSPS *sps, int x0, int y0, int nPbW, int nPbH, int refIdxLx, Mv *mvLXCol, int X)
static int derive_temporal_colocated_mvs(const HEVCContext *s, MvField temp_col, int refIdxLx, Mv *mvLXCol, int X, int colPic, const RefPicList *refPicList_col)
static av_always_inline int compare_mv_ref_idx(struct MvField A, struct MvField B)
static int check_mvset(Mv *mvLXCol, const Mv *mvCol, int colPic, int poc, const RefPicList *refPicList, int X, int refIdxLx, const RefPicList *refPicList_col, int listCol, int refidxCol)
#define MRG_MAX_NUM_CANDS
#define SAMPLE_CTB(tab, x, y)
static void FUNC dmvr(int16_t *dst, const uint8_t *_src, const ptrdiff_t _src_stride, const int height, const intptr_t mx, const intptr_t my, const int width)
static const int8_t mv[256][2]
static int shift(int a, int b)
static av_always_inline av_const double round(double x)
static const uint16_t mask[17]
#define LOCAL_ALIGNED_8(t, v,...)
#define FF_ARRAY_ELEMS(a)
static const float pred[4]
enum PredMode pred_mode
PredMode.
MvField hmvp[MAX_NUM_HMVP_CANDS]
HmvpCandList.
int num_hmvp_ibc
NumHmvpIbcCand.
MvField hmvp_ibc[MAX_NUM_HMVP_CANDS]
HmvpIbcCandList.
Mv mv[2][MAX_CONTROL_POINTS]
uint8_t hpel_if_idx
hpelIfIdx
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
const VVCLocalContext * lc
Neighbour neighbours[NUM_NBS]
uint8_t inter_affine_flag
int16_t diff_mv_y[2][AFFINE_MIN_BLOCK_SIZE *AFFINE_MIN_BLOCK_SIZE]
diffMvLX
uint8_t gpm_partition_idx
int16_t diff_mv_x[2][AFFINE_MIN_BLOCK_SIZE *AFFINE_MIN_BLOCK_SIZE]
diffMvLX
VVCRefPic refs[VVC_MAX_REF_ENTRIES]
const VVCSPS * sps
RefStruct reference.
int32_t poc
PicOrderCntVal.
const H266RawPictureHeader * r
int is_scaled
RprConstraintsActiveFlag.
const H266RawSliceHeader * r
RefStruct reference.
static int ref[MAX_W *MAX_W]
static AVFormatContext * ctx
static float compare(const AVFrame *haystack, const AVFrame *obj, int offx, int offy)
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
static double b1(void *priv, double x, double y)
static double a1(void *priv, double x, double y)
const uint8_t ff_vvc_gpm_angle_idx[VVC_GPM_NUM_PARTITION]
const int8_t ff_vvc_gpm_distance_lut[VVC_GPM_NUM_ANGLES]
const uint8_t ff_vvc_gpm_distance_idx[VVC_GPM_NUM_PARTITION]
static int ibc_history_candidates(const VVCLocalContext *lc, const int merge_idx, Mv *cand_list, int *nb_merge_cand)
void ff_vvc_round_mv(Mv *mv, const int lshift, const int rshift)
static void sb_temproal_luma_motion(const VVCLocalContext *lc, const int x_ctb, const int y_ctb, const Mv *temp_mv, int x, int y, uint8_t *pred_flag, Mv *mv)
static int mvp_spatial_candidates(const VVCLocalContext *lc, const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift, Mv *mv, int *nb_merge_cand)
void ff_vvc_luma_mv_merge_mode(VVCLocalContext *lc, const int merge_idx, const int ciip_flag, MvField *mv)
static int is_fallback_mode(const SubblockParams *sp, const PredFlag pred_flag)
int ff_vvc_luma_mv_merge_ibc(VVCLocalContext *lc, const int merge_idx, Mv *mv)
static int mvp_from_nbs(NeighbourContext *ctx, const NeighbourIdx *nbs, const int num_nbs, const int lx, const int8_t *ref_idx, const int amvr_shift, Mv *cps, const int num_cps)
void ff_vvc_store_gpm_mvf(const VVCLocalContext *lc, const PredictionUnit *pu)
static void mv_merge_zero_motion_candidate(const VVCLocalContext *lc, const int merge_idx, MvField *cand_list, int num_cands)
static int sb_temporal_luma_motion_data(const VVCLocalContext *lc, const MvField *a1, const int x_ctb, const int y_ctb, MvField *ctr_mvf, Mv *temp_mv)
static void affine_mvp_const2(const int idx, Mv *cps, const int num_cp)
static int affine_merge_const5(const MvField *c0, const MvField *c1, MotionInfo *mi)
static const MvField * mv_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand)
int ff_vvc_no_backward_pred_flag(const VVCLocalContext *lc)
static int affine_merge_from_nbs(NeighbourContext *ctx, const NeighbourIdx *nbs, const int num_nbs, MotionInfo *cand)
static int affine_merge_const4(const MvField *c1, const MvField *c2, const MvField *c3, MotionInfo *mi)
void ff_vvc_store_mvf(const VVCLocalContext *lc, const MvField *mvf)
static int affine_mvp_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, const int lx, const int8_t *ref_idx, Mv *cps, const int num_cp)
static int mvp_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, const int lx, const int8_t *ref_idx, Mv *mv)
static int affine_merge_const1(const MvField *c0, const MvField *c1, const MvField *c2, MotionInfo *mi)
static void affine_merge_zero_motion(const VVCLocalContext *lc, MotionInfo *mi)
static int sb_temporal_merge_candidate(const VVCLocalContext *lc, NeighbourContext *nctx, PredictionUnit *pu)
static int compare_l0_mv(const MvField *n, const MvField *o)
void ff_vvc_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi)
static av_always_inline int is_same_mer(const VVCFrameContext *fc, const int xN, const int yN, const int xP, const int yP)
static void update_hmvp(MvField *hmvp, int *num_hmvp, const MvField *mvf, int(*compare)(const MvField *n, const MvField *o))
static int mvp_temporal_candidates(const VVCLocalContext *lc, const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift, Mv *mv, int *num_cands)
static void affine_cps_from_nb(const VVCLocalContext *lc, const int x_nb, int y_nb, const int nbw, const int nbh, const int lx, Mv *cps, int num_cps)
static void derive_subblock_diff_mvs(const VVCLocalContext *lc, PredictionUnit *pu, const SubblockParams *sp, const int lx)
static int is_available(const VVCFrameContext *fc, const int x0, const int y0)
static int affine_mvp_const1(NeighbourContext *nctx, const int lx, const int8_t ref_idx, const int amvr_shift, Mv *cps, int *available)
void ff_vvc_sb_mv_merge_mode(VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu)
static int derive_cb_prof_flag_lx(const VVCLocalContext *lc, const PredictionUnit *pu, int lx, int is_fallback)
static void ibc_add_mvp(Mv *mv, Mv *mvp, const int amvr_shift)
void ff_vvc_luma_mv_merge_gpm(VVCLocalContext *lc, const int merge_gpm_idx[2], MvField *mv)
static int mvp_history_candidates(const VVCLocalContext *lc, const int mvp_lx_flag, const int lx, const int8_t ref_idx, const int amvr_shift, Mv *mv, int num_cands)
void ff_vvc_update_hmvp(VVCLocalContext *lc, const MotionInfo *mi)
#define MVP_FROM_NBS(nbs)
static void mvp(const VVCLocalContext *lc, const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift, Mv *mv)
static const MvField * mv_merge_from_nb(NeighbourContext *ctx, const NeighbourIdx nb)
static void mv_merge_mode(const VVCLocalContext *lc, const int merge_idx, MvField *cand_list)
MvField * ff_vvc_get_mvf(const VVCFrameContext *fc, const int x0, const int y0)
static av_always_inline PredMode pred_flag_to_mode(PredFlag pred)
#define AFFINE_MVP_FROM_NBS(nbs)
void ff_vvc_set_intra_mvf(const VVCLocalContext *lc, const bool dmvr, const PredFlag pf, const bool ciip_flag)
static int mv_merge_temporal_candidate(const VVCLocalContext *lc, MvField *cand)
static int mv_merge_history_candidates(const VVCLocalContext *lc, const int merge_idx, const MvField **nb_list, MvField *cand_list, int *num_cands)
static int affine_merge_const_candidates(const VVCLocalContext *lc, MotionInfo *mi, NeighbourContext *nctx, const int merge_subblock_idx, int num_cands)
static int mv_merge_pairwise_candidate(MvField *cand_list, const int num_cands, const int is_b)
static av_always_inline int compare_pf_ref_idx(const MvField *A, const struct MvField *B, const struct MvField *C, const int lx)
#define MV_MERGE_FROM_NB(nb)
static int ibc_check_mv(VVCLocalContext *lc, Mv *mv)
static const MvField * derive_corner_mvf(NeighbourContext *ctx, const NeighbourIdx *neighbour, const int num_neighbour)
void ff_vvc_clip_mv(Mv *mv)
static int affine_merge_const3(const MvField *c0, const MvField *c2, const MvField *c3, MotionInfo *mi)
static int affine_neighbour_cb(const VVCFrameContext *fc, const int x_nb, const int y_nb, int *x_cb, int *y_cb, int *cbw, int *cbh)
void ff_vvc_mv_scale(Mv *dst, const Mv *src, int td, int tb)
int ff_vvc_mvp_ibc(VVCLocalContext *lc, const int mvp_l0_flag, const int amvr_shift, Mv *mv)
#define AFFINE_MVP_CONSTRUCTED_CP(cands, cp)
static void store_cp_mv(const VVCLocalContext *lc, const MotionInfo *mi, const int lx)
static void affine_mvp(const VVCLocalContext *lc, const int mvp_lx_flag, const int lx, const int8_t *ref_idx, const int amvr_shift, MotionModelIdc motion_model_idc, Mv *cps)
#define DERIVE_CORNER_MV(nbs)
static void init_subblock_params(SubblockParams *sp, const MotionInfo *mi, const int cb_width, const int cb_height, const int lx)
static int affine_merge_const2(const MvField *c0, const MvField *c1, const MvField *c3, MotionInfo *mi)
static int affine_mvp_constructed_cp(NeighbourContext *ctx, const NeighbourIdx *neighbour, const int num_neighbour, const int lx, const int8_t ref_idx, const int amvr_shift, Mv *cp)
static av_always_inline int is_greater_mer(const VVCFrameContext *fc, const int x0, const int y0, const int x0_br, const int y0_br)
static av_always_inline void sb_clip_location(const VVCLocalContext *lc, const int x_ctb, const int y_ctb, const Mv *temp_mv, int *x, int *y)
static int affine_merge_const6(const MvField *c0, const MvField *c2, const int cb_width, const int cb_height, MotionInfo *mi)
#define TAB_CP_MV(lx, x, y)
static void init_neighbour_context(NeighbourContext *ctx, const VVCLocalContext *lc)
static int affine_merge_candidate(const VVCLocalContext *lc, const int x_cand, const int y_cand, MotionInfo *mi)
void ff_vvc_store_sb_mvs(const VVCLocalContext *lc, PredictionUnit *pu)
static int sb_mv_merge_mode(const VVCLocalContext *lc, const int merge_subblock_idx, PredictionUnit *pu)
void ff_vvc_set_mvf(const VVCLocalContext *lc, const int x0, const int y0, const int w, const int h, const MvField *mvf)
#define DERIVE_TEMPORAL_COLOCATED_MVS(sb_flag)
static int mv_merge_spatial_candidates(const VVCLocalContext *lc, const int merge_idx, const MvField **nb_list, MvField *cand_list, int *nb_merge_cand)
static int ibc_spatial_candidates(const VVCLocalContext *lc, const int merge_idx, Mv *const cand_list, int *nb_merge_cand)
#define AFFINE_MERGE_FROM_NBS(nbs)
static av_always_inline void mv_compression(Mv *motion)
void ff_vvc_store_mv(const VVCLocalContext *lc, const MotionInfo *mi)
static int check_available(Neighbour *n, const VVCLocalContext *lc, const int check_mer)
static int is_a0_available(const VVCLocalContext *lc, const CodingUnit *cu)
static void ibc_merge_candidates(VVCLocalContext *lc, const int merge_idx, Mv *mv)
void ff_vvc_affine_mvp(VVCLocalContext *lc, const int *mvp_lx_flag, const int amvr_shift, MotionInfo *mi)