Add overhang to border to get better gradients Some improvement in coding results with warped_causal_interintra mode is observed.
diff --git a/aom_util/debug_util.c b/aom_util/debug_util.c index ba33088..0846b24 100644 --- a/aom_util/debug_util.c +++ b/aom_util/debug_util.c
@@ -100,8 +100,8 @@ static int frame_buf_idx_r = 0; static int frame_buf_idx_w = 0; #define MAX_FRAME_BUF_NUM 6 -#define MAX_FRAME_STRIDE 1280 -#define MAX_FRAME_HEIGHT 720 +#define MAX_FRAME_STRIDE 1920 +#define MAX_FRAME_HEIGHT 1080 static uint16_t frame_pre[MAX_FRAME_BUF_NUM][3] [MAX_FRAME_STRIDE * MAX_FRAME_HEIGHT]; // prediction only
diff --git a/av1/common/av1_common_int.h b/av1/common/av1_common_int.h index a1dac85..40bdfd8 100644 --- a/av1/common/av1_common_int.h +++ b/av1/common/av1_common_int.h
@@ -3579,8 +3579,10 @@ static INLINE int motion_mode_allowed(const AV1_COMMON *cm, const MACROBLOCKD *xd, const CANDIDATE_MV *ref_mv_stack, - const MB_MODE_INFO *mbmi) { + const MB_MODE_INFO *mbmi, + int ref_base_qindex) { (void)ref_mv_stack; + (void)ref_base_qindex; const BLOCK_SIZE bsize = mbmi->sb_type[PLANE_TYPE_Y]; int enabled_motion_modes = cm->features.enabled_motion_modes;
diff --git a/av1/common/blockd.h b/av1/common/blockd.h index 5778002..ef10309 100644 --- a/av1/common/blockd.h +++ b/av1/common/blockd.h
@@ -470,6 +470,8 @@ MOTION_MODE motion_mode; /*! \brief Number of samples used by spatial warp prediction */ uint8_t num_proj_ref; + /*! \brief Number of samples used by spatial warp prediction post pruning */ + uint8_t num_proj_ref_pruned; /*! \brief The number of overlapped neighbors above/left for obmc/warp motion * mode. */ uint8_t overlappable_neighbors[2];
diff --git a/av1/common/reconinter.c b/av1/common/reconinter.c index eef878e..bf3ced3 100644 --- a/av1/common/reconinter.c +++ b/av1/common/reconinter.c
@@ -2677,33 +2677,48 @@ // motion vector mv so that the pixels are correctly aligned. // ref is an integer shifted buffer based on floor of the motion vector mv. // Note top is assumed to have alllocaton of at least (border + -// inner_border) * bw, with top_stride being at least bw. +// inner_border) * (bw + 2 * overhang), with top_stride being at least +// bw + 2 * overhang. // Likewise left is assumed to have alllocaton of at least (border + -// inner_border) * bh, with left_stride being at least border + inner_border. +// inner_border) * (bh + 2 * overhang), with left_stride being at least +// border + inner_border. void av1_prepare_inter_topleft(const uint16_t *ref, int ref_stride, BLOCK_SIZE bsize, int border, int inner_border, - MV mv, uint16_t *top, int top_stride, - uint16_t *left, int left_stride, int bd) { + int overhang, MV mv, uint16_t *top, + int top_stride, uint16_t *left, int left_stride, + int bd) { const int phase_x = (mv.col << 1) & 15; const int phase_y = (mv.row << 1) & 15; const int bw = block_size_wide[bsize]; const int bh = block_size_high[bsize]; uint16_t scratch[MAX_INTERINTRA_TOPLEFT_SIZE]; - int scratch_stride = bw; - for (int i = -border; i < 2 + inner_border; ++i) { - cubic_phase_shift1(ref + i * ref_stride, 1, bw, phase_x, 1, - scratch + (i + border) * scratch_stride, 1); + if (phase_x == 0 && phase_y == 0) { + for (int i = 0; i < border + inner_border; ++i) { + memcpy(top + i * top_stride, ref + (i - border) * ref_stride - overhang, + (bw + 2 * overhang) * sizeof(*top)); + } + for (int i = 0; i < bh + 2 * overhang; ++i) { + memcpy(left + i * left_stride, ref + (i - overhang) * ref_stride - border, + (border + inner_border) * sizeof(*left)); + } + return; } - for (int i = 0; i < bw; ++i) { + int scratch_stride = bw + 2 * overhang; + for (int i = -border; i < 2 + inner_border; ++i) { + cubic_phase_shift1(ref + i * ref_stride - overhang, 1, bw + 2 * overhang, + phase_x, 1, scratch + (i + border) * scratch_stride, 1); + } + for (int i = 0; i < bw + 2 * overhang; ++i) { cubic_phase_shift2(scratch + i, scratch_stride, border + inner_border, phase_y, 0, top + i, top_stride, bd); } scratch_stride = border + inner_border + 2; for (int i = -border; i < 2 + inner_border; ++i) - cubic_phase_shift1(ref + i, ref_stride, bh, phase_y, 1, - scratch + i + border, scratch_stride); - for (int i = 0; i < bh; ++i) { + cubic_phase_shift1(ref + i - overhang * ref_stride, ref_stride, + bh + 2 * overhang, phase_y, 1, scratch + i + border, + scratch_stride); + for (int i = 0; i < bh + 2 * overhang; ++i) { cubic_phase_shift2(scratch + i * scratch_stride, 1, border + inner_border, phase_x, 0, left + i * left_stride, 1, bd); }
diff --git a/av1/common/reconinter.h b/av1/common/reconinter.h index 295a09f..753688f 100644 --- a/av1/common/reconinter.h +++ b/av1/common/reconinter.h
@@ -46,13 +46,16 @@ 2 // May be neded to calculate gradient. // This border is one the inner side so // the load area does not change. -#define MAX_INTERINTRA_TOPLEFT_SIZE \ - ((MAX_INTERINTRA_BORDER + MAX_INTERINTRA_INNER_BORDER + 2) * MAX_SB_SIZE) +#define MAX_INTERINTRA_OVERHANG 1 +#define MAX_INTERINTRA_TOPLEFT_SIZE \ + ((MAX_INTERINTRA_BORDER + MAX_INTERINTRA_INNER_BORDER + 2) * \ + (2 * MAX_INTERINTRA_OVERHANG + MAX_SB_SIZE)) void av1_prepare_inter_topleft(const uint16_t *ref, int ref_stride, BLOCK_SIZE bsize, int border, int inner_border, - MV mv, uint16_t *top, int top_stride, - uint16_t *left, int left_stride, int bd); + int overhang, MV mv, uint16_t *top, + int top_stride, uint16_t *left, int left_stride, + int bd); #endif // CONFIG_THICK_INTERINTRA_BORDER #if !CONFIG_WEDGE_MOD_EXT
diff --git a/av1/common/warped_motion.c b/av1/common/warped_motion.c index 6f0156a..3fd82b6 100644 --- a/av1/common/warped_motion.c +++ b/av1/common/warped_motion.c
@@ -1395,10 +1395,30 @@ #endif // CONFIG_TEMPORAL_GLOBAL_MV #if CONFIG_INTERINTRA_WARP -static int get_gradient(const uint16_t *x, int stride) { +// Note ext1 = 1 corresponds to the case when 2 prior samples are available +// in the beginning of the sequence and so no padding is needed. +// ext1 = 0 corresponds to the case when only 1 prior sample is available +// in the beginning of the sequence. +// Likewise ext2 = 1 corresponds to the case when 2 external samples are +// available at the end of the sequence and so no padding is needed at the end. +// ext2 = 0 corresponds to the case when only 1 xeternal sample is available +// at the end of the sequence. +static int get_gradient(const uint16_t *x, int stride, int ext1, int ext2) { static const int16_t gradient[2] = { 88, -12 }; - int g = (x[stride] - x[-stride]) * gradient[0] + - (x[2 * stride] - x[-2 * stride]) * gradient[1]; + int g; + if (ext1 && ext2) { + g = (x[stride] - x[-stride]) * gradient[0] + + (x[2 * stride] - x[-2 * stride]) * gradient[1]; + } else if (!ext1 && ext2) { + g = (x[stride] - x[-stride]) * gradient[0] + + (x[2 * stride] - 2 * x[-1 * stride] + x[0]) * gradient[1]; + } else if (ext1 && !ext2) { + g = (x[stride] - x[-stride]) * gradient[0] + + (2 * x[1 * stride] - x[0] - x[-2 * stride]) * gradient[1]; + } else { + g = (x[stride] - x[-stride]) * gradient[0] + + (2 * x[1 * stride] - 2 * x[-1 * stride]) * gradient[1]; + } g = ROUND_POWER_OF_TWO_SIGNED(g, FILTER_BITS); return g; } @@ -1410,6 +1430,7 @@ * use around this reference block. * mv - motion vector */ +#define GRAD_THRESH 1 static int find_interintra_rotzoom_int(const uint16_t *src, int src_stride, const uint16_t *ref, int ref_stride, BLOCK_SIZE bsize, MV mv, @@ -1417,25 +1438,33 @@ int mi_col, int bd) { const int border = MAX_INTERINTRA_BORDER; const int inner_border = MAX_INTERINTRA_INNER_BORDER; + const int overhang = MAX_INTERINTRA_OVERHANG; const int bw = block_size_wide[bsize]; const int bh = block_size_high[bsize]; uint16_t top[MAX_INTERINTRA_TOPLEFT_SIZE]; uint16_t left[MAX_INTERINTRA_TOPLEFT_SIZE]; - const int top_stride = bw; + const int top_stride = bw + 2 * overhang; const int left_stride = border + inner_border; - av1_prepare_inter_topleft(ref, ref_stride, bsize, border, inner_border, mv, - top, top_stride, left, left_stride, bd); + av1_prepare_inter_topleft(ref, ref_stride, bsize, border, inner_border, + overhang, mv, top, top_stride, left, left_stride, + bd); + const int off = 1; int32_t A[2][2] = { { 0, 0 }, { 0, 0 } }; int32_t B[2] = { 0, 0 }; - for (int i = 2; i < border; ++i) { - for (int j = 2; j < bw - 2; ++j) { - const int d = (*(top + i * top_stride + j) - + for (int i = 1; i < border; ++i) { + for (int j = off; j < bw - off; ++j) { + const int d = (*(top + i * top_stride + j + overhang) - *(src + (i - border) * src_stride + j)); const int y = (i - border) - (bh / 2 - 1); const int x = j - (bw / 2 - 1); - const int gx = get_gradient(top + i * top_stride + j, 1); - const int gy = get_gradient(top + i * top_stride + j, top_stride); + const int gx = get_gradient(top + i * top_stride + j + overhang, 1, + j > 1 - overhang, j < bw - 2 + overhang); + const int gy = get_gradient(top + i * top_stride + j + overhang, + top_stride, i > 1, 1); +#if GRAD_THRESH + if (abs(gx) < GRAD_THRESH && abs(gy) < GRAD_THRESH) continue; +#endif // GRAD_THRESH const int p1 = x * gx + y * gy; const int p2 = y * gx - x * gy; A[0][0] += p1 * p1; @@ -1445,14 +1474,20 @@ B[1] += p2 * d; } } - for (int i = 2; i < bh - 2; ++i) { - for (int j = 2; j < border; ++j) { - const int d = (*(left + i * left_stride + j) - + for (int i = off; i < bh - off; ++i) { + for (int j = 1; j < border; ++j) { + const int d = (*(left + (i + overhang) * left_stride + j) - *(src + i * src_stride + j - border)); const int y = i - (bh / 2 - 1); const int x = (j - border) - (bw / 2 - 1); - const int gx = get_gradient(left + i * left_stride + j, 1); - const int gy = get_gradient(left + i * left_stride + j, left_stride); + const int gx = + get_gradient(left + (i + overhang) * left_stride + j, 1, j > 1, 1); + const int gy = + get_gradient(left + (i + overhang) * left_stride + j, left_stride, + i > 1 - overhang, i < bh - 2 + overhang); +#if GRAD_THRESH + if (abs(gx) < GRAD_THRESH && abs(gy) < GRAD_THRESH) continue; +#endif // GRAD_THRESH const int p1 = x * gx + y * gy; const int p2 = y * gx - x * gy; A[0][0] += p1 * p1; @@ -1506,10 +1541,9 @@ } int av1_find_projection_interintra(const MACROBLOCKD *xd, BLOCK_SIZE bsize, - MV mv, WarpedMotionParams *wm_params) { + const uint16_t *dst, int dst_stride, MV mv, + WarpedMotionParams *wm_params) { const struct macroblockd_plane *pd = &xd->plane[0]; - const int dst_stride = pd->dst.stride; - uint16_t *const dst = pd->dst.buf; const int mi_row = xd->mi_row; const int mi_col = xd->mi_col; @@ -1528,12 +1562,11 @@ } int av1_find_projection_interintra_ext(const MACROBLOCKD *xd, BLOCK_SIZE bsize, + const uint16_t *dst, int dst_stride, MV mv, WarpedMotionParams *wm_params, int width, int height, uint16_t *tmpbuf) { const struct macroblockd_plane *pd = &xd->plane[0]; - const int dst_stride = pd->dst.stride; - uint16_t *const dst = pd->dst.buf; const int mi_row = xd->mi_row; const int mi_col = xd->mi_col;
diff --git a/av1/common/warped_motion.h b/av1/common/warped_motion.h index f566cad..bd55357 100644 --- a/av1/common/warped_motion.h +++ b/av1/common/warped_motion.h
@@ -326,8 +326,10 @@ #endif // CONFIG_TEMPORAL_GLOBAL_MV #if CONFIG_INTERINTRA_WARP int av1_find_projection_interintra(const MACROBLOCKD *xd, BLOCK_SIZE bsize, - MV mv, WarpedMotionParams *wm_params); + const uint16_t *dst, int dst_stride, MV mv, + WarpedMotionParams *wm_params); int av1_find_projection_interintra_ext(const MACROBLOCKD *xd, BLOCK_SIZE bsize, + const uint16_t *dst, int dst_stride, MV mv, WarpedMotionParams *wm_params, int width, int height, uint16_t *tmpbuf); #endif // CONFIG_INTERINTRA_WARP
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index 0a4a5ea..bdb5dd5 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c
@@ -1337,9 +1337,9 @@ mbmi->wm_params[0].wmtype = ROTZOOM; mbmi->wm_params[0].invalid = 0; MV mv = mbmi->mv[0].as_mv; - if (av1_find_projection_interintra_ext(xd, bsize, mv, &mbmi->wm_params[0], - cm->width, cm->height, - dcb->mc_buf[0])) { + if (av1_find_projection_interintra_ext( + xd, bsize, xd->plane[0].dst.buf, xd->plane[0].dst.stride, mv, + &mbmi->wm_params[0], cm->width, cm->height, dcb->mc_buf[0])) { #if WARPED_MOTION_DEBUG printf("Warning: unexpected warped model from aomenc\n"); #endif
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c index 582514c..55751d6 100644 --- a/av1/decoder/decodemv.c +++ b/av1/decoder/decodemv.c
@@ -449,8 +449,10 @@ #if CONFIG_WARP_REF_LIST mbmi->max_num_warp_candidates = 0; #endif // CONFIG_WARP_REF_LIST + const RefCntBuffer *const refbuf = get_ref_frame_buf(cm, mbmi->ref_frame[0]); const int allowed_motion_modes = - motion_mode_allowed(cm, xd, xd->ref_mv_stack[mbmi->ref_frame[0]], mbmi); + motion_mode_allowed(cm, xd, xd->ref_mv_stack[mbmi->ref_frame[0]], mbmi, + refbuf ? refbuf->base_qindex : -1); #if CONFIG_WARPMV if (mbmi->mode == WARPMV) { @@ -2680,6 +2682,7 @@ #endif // CONFIG_TIP !mbmi->skip_mode && !has_second_ref(mbmi)) { mbmi->num_proj_ref = av1_findSamples(cm, xd, pts, pts_inref); + mbmi->num_proj_ref_pruned = mbmi->num_proj_ref; } av1_count_overlappable_neighbors(cm, xd); mbmi->motion_mode = read_motion_mode(cm, xd, mbmi, r); @@ -2803,6 +2806,7 @@ #endif // CONFIG_TIP !mbmi->skip_mode && !has_second_ref(mbmi)) { mbmi->num_proj_ref = av1_findSamples(cm, xd, pts, pts_inref); + mbmi->num_proj_ref_pruned = mbmi->num_proj_ref; } av1_count_overlappable_neighbors(cm, xd); @@ -2865,6 +2869,7 @@ #endif // CONFIG_TIP !mbmi->skip_mode && !has_second_ref(mbmi)) { mbmi->num_proj_ref = av1_findSamples(cm, xd, pts, pts_inref); + mbmi->num_proj_ref_pruned = mbmi->num_proj_ref; } av1_count_overlappable_neighbors(cm, xd); @@ -2942,12 +2947,12 @@ MV mv = mbmi->mv[0].as_mv; if (mbmi->num_proj_ref > 1) { - mbmi->num_proj_ref = av1_selectSamples(&mbmi->mv[0].as_mv, pts, pts_inref, - mbmi->num_proj_ref, bsize); + mbmi->num_proj_ref_pruned = av1_selectSamples( + &mbmi->mv[0].as_mv, pts, pts_inref, mbmi->num_proj_ref, bsize); } - if (av1_find_projection(mbmi->num_proj_ref, pts, pts_inref, bsize, mv, - &mbmi->wm_params[0], mi_row, mi_col)) { + if (av1_find_projection(mbmi->num_proj_ref_pruned, pts, pts_inref, bsize, + mv, &mbmi->wm_params[0], mi_row, mi_col)) { #if WARPED_MOTION_DEBUG printf("Warning: unexpected warped model from aomenc\n"); #endif @@ -3006,11 +3011,11 @@ mbmi->wm_params.invalid = 0; if (mbmi->num_proj_ref > 1) { - mbmi->num_proj_ref = av1_selectSamples(&mbmi->mv[0].as_mv, pts, pts_inref, - mbmi->num_proj_ref, bsize); + mbmi->num_proj_ref_pruned = av1_selectSamples( + &mbmi->mv[0].as_mv, pts, pts_inref, mbmi->num_proj_ref, bsize); } - if (av1_find_projection(mbmi->num_proj_ref, pts, pts_inref, bsize, + if (av1_find_projection(mbmi->num_proj_ref_pruned, pts, pts_inref, bsize, mbmi->mv[0].as_mv, &mbmi->wm_params, mi_row, mi_col)) { #if WARPED_MOTION_DEBUG
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index eda9230..a07a261 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c
@@ -498,8 +498,10 @@ const AV1_COMMON *cm, MACROBLOCKD *xd, const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT_FRAME *mbmi_ext_frame, aom_writer *w) { const BLOCK_SIZE bsize = mbmi->sb_type[PLANE_TYPE_Y]; + const RefCntBuffer *const refbuf = get_ref_frame_buf(cm, mbmi->ref_frame[0]); const int allowed_motion_modes = - motion_mode_allowed(cm, xd, mbmi_ext_frame->ref_mv_stack, mbmi); + motion_mode_allowed(cm, xd, mbmi_ext_frame->ref_mv_stack, mbmi, + refbuf ? refbuf->base_qindex : -1); assert((allowed_motion_modes & (1 << mbmi->motion_mode)) != 0); assert((cm->features.enabled_motion_modes & (1 << mbmi->motion_mode)) != 0);
diff --git a/av1/encoder/mcomp.c b/av1/encoder/mcomp.c index 8539951..601e6b5 100644 --- a/av1/encoder/mcomp.c +++ b/av1/encoder/mcomp.c
@@ -5178,7 +5178,7 @@ #else WarpedMotionParams best_wm_params = mbmi->wm_params; #endif // CONFIG_EXTENDED_WARP_PREDICTION - int best_num_proj_ref = mbmi->num_proj_ref; + int best_num_proj_ref_pruned = mbmi->num_proj_ref_pruned; unsigned int bestmse; const SubpelMvLimits *mv_limits = &ms_params->mv_limits; @@ -5217,16 +5217,17 @@ memcpy(pts, pts0, total_samples * 2 * sizeof(*pts0)); memcpy(pts_inref, pts_inref0, total_samples * 2 * sizeof(*pts_inref0)); if (total_samples > 1) - mbmi->num_proj_ref = + mbmi->num_proj_ref_pruned = av1_selectSamples(&this_mv, pts, pts_inref, total_samples, bsize); #if CONFIG_EXTENDED_WARP_PREDICTION - if (!av1_find_projection(mbmi->num_proj_ref, pts, pts_inref, bsize, - this_mv, &mbmi->wm_params[0], mi_row, + if (!av1_find_projection(mbmi->num_proj_ref_pruned, pts, pts_inref, + bsize, this_mv, &mbmi->wm_params[0], mi_row, mi_col)) { #else - if (!av1_find_projection(mbmi->num_proj_ref, pts, pts_inref, bsize, - this_mv, &mbmi->wm_params, mi_row, mi_col)) { + if (!av1_find_projection(mbmi->num_proj_ref_pruned, pts, pts_inref, + bsize, this_mv, &mbmi->wm_params, mi_row, + mi_col)) { #endif // CONFIG_EXTENDED_WARP_PREDICTION thismse = compute_motion_cost(xd, cm, ms_params, bsize, &this_mv); @@ -5237,7 +5238,7 @@ #else best_wm_params = mbmi->wm_params; #endif // CONFIG_EXTENDED_WARP_PREDICTION - best_num_proj_ref = mbmi->num_proj_ref; + best_num_proj_ref_pruned = mbmi->num_proj_ref_pruned; bestmse = thismse; } } @@ -5258,16 +5259,16 @@ #else mbmi->wm_params = best_wm_params; #endif // CONFIG_EXTENDED_WARP_PREDICTION - mbmi->num_proj_ref = best_num_proj_ref; + mbmi->num_proj_ref_pruned = best_num_proj_ref_pruned; return bestmse; } #if CONFIG_INTERINTRA_WARP // Refines MV in a small range unsigned int av1_refine_warped_interintra_mv( - MACROBLOCKD *xd, const AV1_COMMON *const cm, - const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, BLOCK_SIZE bsize, - WARP_SEARCH_METHOD search_method, int num_iterations) { + MACROBLOCKD *xd, const AV1_COMMON *const cm, const uint16_t *dst, + int dst_stride, const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, + BLOCK_SIZE bsize, WARP_SEARCH_METHOD search_method, int num_iterations) { MB_MODE_INFO *mbmi = xd->mi[0]; const MV *neighbors = warp_search_info[search_method].neighbors; @@ -5313,10 +5314,10 @@ best_mv->col + neighbors[idx].col * (1 << mv_shift) }; if (av1_is_subpelmv_in_range(mv_limits, this_mv)) { #if CONFIG_EXTENDED_WARP_PREDICTION - if (!av1_find_projection_interintra(xd, bsize, this_mv, + if (!av1_find_projection_interintra(xd, bsize, dst, dst_stride, this_mv, &mbmi->wm_params[0])) { #else - if (!av1_find_projection_interintra(xd, bsize, this_mv, + if (!av1_find_projection_interintra(xd, bsize, dst, dst_stride, this_mv, &mbmi->wm_params)) { #endif // CONFIG_EXTENDED_WARP_PREDICTION thismse = compute_motion_cost(xd, cm, ms_params, bsize, &this_mv);
diff --git a/av1/encoder/mcomp.h b/av1/encoder/mcomp.h index da753ce..5bd9051 100644 --- a/av1/encoder/mcomp.h +++ b/av1/encoder/mcomp.h
@@ -502,9 +502,9 @@ #if CONFIG_INTERINTRA_WARP unsigned int av1_refine_warped_interintra_mv( - MACROBLOCKD *xd, const AV1_COMMON *const cm, - const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, BLOCK_SIZE bsize, - WARP_SEARCH_METHOD search_method, int num_iterations); + MACROBLOCKD *xd, const AV1_COMMON *const cm, const uint16_t *dst, + int dst_stride, const SUBPEL_MOTION_SEARCH_PARAMS *ms_params, + BLOCK_SIZE bsize, WARP_SEARCH_METHOD search_method, int num_iterations); #endif // CONFIG_INTERINTRA_WARP #if CONFIG_EXTENDED_WARP_PREDICTION
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c index 410216d..e2ed6cf 100644 --- a/av1/encoder/partition_search.c +++ b/av1/encoder/partition_search.c
@@ -1300,8 +1300,11 @@ } #endif // CONFIG_BAWP #if CONFIG_EXTENDED_WARP_PREDICTION + const RefCntBuffer *const refbuf = + get_ref_frame_buf(cm, mbmi->ref_frame[0]); const int allowed_motion_modes = motion_mode_allowed( - cm, xd, mbmi_ext->ref_mv_stack[mbmi->ref_frame[0]], mbmi); + cm, xd, mbmi_ext->ref_mv_stack[mbmi->ref_frame[0]], mbmi, + refbuf ? refbuf->base_qindex : -1); MOTION_MODE motion_mode = mbmi->motion_mode; #if CONFIG_WARPMV @@ -1891,8 +1894,11 @@ const int seg_ref_active = 0; if (!seg_ref_active && inter_block) { #if CONFIG_EXTENDED_WARP_PREDICTION + const RefCntBuffer *const refbuf = + get_ref_frame_buf(cm, mbmi->ref_frame[0]); const int allowed_motion_modes = motion_mode_allowed( - cm, xd, x->mbmi_ext->ref_mv_stack[mbmi->ref_frame[0]], mbmi); + cm, xd, x->mbmi_ext->ref_mv_stack[mbmi->ref_frame[0]], mbmi, + refbuf ? refbuf->base_qindex : -1); if (mbmi->motion_mode != INTERINTRA) { if (allowed_motion_modes & (1 << OBMC_CAUSAL)) { td->rd_counts.obmc_used[bsize][mbmi->motion_mode == OBMC_CAUSAL]++;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index 78677de..a54904f 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c
@@ -1666,19 +1666,17 @@ (void)tile_data; av1_invalid_rd_stats(&best_rd_stats); aom_clear_system_state(); - mbmi->num_proj_ref = 1; // assume num_proj_ref >=1 + mbmi->num_proj_ref = 1; #if CONFIG_WARP_REF_LIST mbmi->warp_ref_idx = 0; mbmi->max_num_warp_candidates = 0; #endif // CONFIG_WARP_REF_LIST #if CONFIG_EXTENDED_WARP_PREDICTION - int allowed_motion_modes = motion_mode_allowed( - cm, xd, mbmi_ext->ref_mv_stack[mbmi->ref_frame[0]], mbmi); - if ((allowed_motion_modes & (1 << WARPED_CAUSAL))) { - // Collect projection samples used in least squares approximation of - // the warped motion parameters if WARPED_CAUSAL is going to be searched. - mbmi->num_proj_ref = av1_findSamples(cm, xd, pts0, pts_inref0); - } + mbmi->num_proj_ref = av1_findSamples(cm, xd, pts0, pts_inref0); + const RefCntBuffer *const refbuf = get_ref_frame_buf(cm, mbmi->ref_frame[0]); + int allowed_motion_modes = + motion_mode_allowed(cm, xd, mbmi_ext->ref_mv_stack[mbmi->ref_frame[0]], + mbmi, refbuf ? refbuf->base_qindex : -1); const int total_samples = mbmi->num_proj_ref; if (total_samples == 0) { // Do not search WARPED_CAUSAL if there are no samples to use to determine @@ -1699,6 +1697,7 @@ last_motion_mode_allowed = OBMC_CAUSAL; } #endif // CONFIG_EXTENDED_WARP_PREDICTION + mbmi->num_proj_ref_pruned = mbmi->num_proj_ref; const MB_MODE_INFO base_mbmi = *mbmi; MB_MODE_INFO best_mbmi; @@ -1917,18 +1916,18 @@ memcpy(pts_inref, pts_inref0, total_samples * 2 * sizeof(*pts_inref0)); // Select the samples according to motion vector difference if (mbmi->num_proj_ref > 1) { - mbmi->num_proj_ref = av1_selectSamples( + mbmi->num_proj_ref_pruned = av1_selectSamples( &mbmi->mv[0].as_mv, pts, pts_inref, mbmi->num_proj_ref, bsize); } // Compute the warped motion parameters with a least squares fit // using the collected samples #if CONFIG_EXTENDED_WARP_PREDICTION - if (!av1_find_projection(mbmi->num_proj_ref, pts, pts_inref, bsize, - mbmi->mv[0].as_mv, &mbmi->wm_params[0], mi_row, - mi_col)) + if (!av1_find_projection(mbmi->num_proj_ref_pruned, pts, pts_inref, + bsize, mbmi->mv[0].as_mv, &mbmi->wm_params[0], + mi_row, mi_col)) #else - if (!av1_find_projection(mbmi->num_proj_ref, pts, pts_inref, bsize, + if (!av1_find_projection(mbmi->num_proj_ref_pruned, pts, pts_inref, bsize, mbmi->mv[0].as_mv, &mbmi->wm_params, mi_row, mi_col)) #endif // CONFIG_EXTENDED_WARP_PREDICTION @@ -2025,11 +2024,13 @@ // Compute the warped motion parameters with a least squares fit // using the collected samples #if CONFIG_EXTENDED_WARP_PREDICTION - if (!av1_find_projection_interintra(xd, bsize, mbmi->mv[0].as_mv, - &mbmi->wm_params[0])) + if (!av1_find_projection_interintra( + xd, bsize, orig_dst->plane[0], orig_dst->stride[0], + mbmi->mv[0].as_mv, &mbmi->wm_params[0])) #else - if (!av1_find_projection_interintra(xd, bsize, mbmi->mv[0].as_mv, - &mbmi->wm_params)) + if (!av1_find_projection_interintra( + xd, bsize, orig_dst->plane[0], orig_dst->stride[0], + mbmi->mv[0].as_mv, &mbmi->wm_params)) #endif // CONFIG_EXTENDED_WARP_PREDICTION { assert(!is_comp_pred); @@ -2054,9 +2055,10 @@ NULL); // Refine MV in a small range. - av1_refine_warped_interintra_mv(xd, cm, &ms_params, bsize, - cpi->sf.mv_sf.warp_search_method, - cpi->sf.mv_sf.warp_search_iters); + av1_refine_warped_interintra_mv( + xd, cm, orig_dst->plane[0], orig_dst->stride[0], &ms_params, + bsize, cpi->sf.mv_sf.warp_search_method, + cpi->sf.mv_sf.warp_search_iters); if (mv0.as_int != mbmi->mv[0].as_int) { // Keep the refined MV and WM parameters. @@ -3106,6 +3108,7 @@ av1_mode_context_analyzer(mbmi_ext->mode_context, mbmi->ref_frame); mbmi->num_proj_ref = 0; + mbmi->num_proj_ref_pruned = 0; mbmi->motion_mode = SIMPLE_TRANSLATION; mbmi->ref_mv_idx = ref_mv_idx; rd_stats->rate += args->ref_frame_cost + args->single_comp_cost; @@ -3158,6 +3161,7 @@ mbmi->motion_mode = SIMPLE_TRANSLATION; mbmi->num_proj_ref = 0; + mbmi->num_proj_ref_pruned = 0; if (is_comp_pred) { // Only compound_average mbmi->interinter_comp.type = COMPOUND_AVERAGE; @@ -4252,6 +4256,7 @@ if (mbmi->ref_frame[1] == INTRA_FRAME) mbmi->ref_frame[1] = NONE_FRAME; mbmi->num_proj_ref = 0; + mbmi->num_proj_ref_pruned = 0; mbmi->motion_mode = SIMPLE_TRANSLATION; mbmi->ref_mv_idx = ref_mv_idx; set_mv_precision(mbmi, mbmi->max_mv_precision); @@ -4347,6 +4352,7 @@ if (mbmi->ref_frame[1] == INTRA_FRAME) mbmi->ref_frame[1] = NONE_FRAME; mbmi->num_proj_ref = 0; + mbmi->num_proj_ref_pruned = 0; mbmi->motion_mode = SIMPLE_TRANSLATION; mbmi->ref_mv_idx = ref_mv_idx; // Compute cost for signalling this DRL index @@ -4597,6 +4603,7 @@ mbmi->ref_frame[1] = NONE_FRAME; mbmi->num_proj_ref = 0; + mbmi->num_proj_ref_pruned = 0; mbmi->motion_mode = SIMPLE_TRANSLATION; mbmi->ref_mv_idx = ref_mv_idx; @@ -4910,7 +4917,6 @@ #if CONFIG_IMPROVED_JMVD } #endif // CONFIG_IMPROVED_JMVD - if (best_rd == INT64_MAX) return INT64_MAX; // re-instate status of the best choice @@ -9047,8 +9053,8 @@ mbmi->num_proj_ref = av1_findSamples(cm, xd, pts, pts_inref); // Select the samples according to motion vector difference if (mbmi->num_proj_ref > 1) - mbmi->num_proj_ref = av1_selectSamples(&mbmi->mv[0].as_mv, pts, pts_inref, - mbmi->num_proj_ref, bsize); + mbmi->num_proj_ref_pruned = av1_selectSamples( + &mbmi->mv[0].as_mv, pts, pts_inref, mbmi->num_proj_ref, bsize); } #if CONFIG_C071_SUBBLK_WARPMV