Commit ac37fa3d authored by David Barker's avatar David Barker Committed by Debargha Mukherjee

Improve rdopt decisions for ext-inter

Relative to previous ext-inter:
lowres: -0.177%
     or -0.029% (with USE_RECT_INTERINTRA = 0)

* When predicting interintra modes, the previous code did not provide
  the intra predictor with the correct context during rdopt. Add an
  explicit 'ctx' parameter to the relevant functions, to provide this
  context.
  This fixes a nondeterminism bug, which was causing test failures in
  *EncoderThreadTest*

* For rectangular blocks, build_intra_predictors_for_interintra needs
  to overwrite part of the context buffer in order to set up the
  correct context for intra prediction. We now restore the original
  contents afterwards.

* Add a flag to enable/disable rectangular interintra prediction;
  disabling improves encoding speed but reduces BDRATE improvement.

Change-Id: I7458c036c7f94df9ab1ba0c7efa79aeaa7e17118
parent 81492267
......@@ -38,6 +38,11 @@ extern "C" {
#define MAX_MB_PLANE 3
#if CONFIG_EXT_INTER
// Should we try rectangular interintra predictions?
#define USE_RECT_INTERINTRA 1
#endif
typedef enum {
KEY_FRAME = 0,
INTER_FRAME = 1,
......@@ -85,6 +90,11 @@ typedef struct PVQ_QUEUE {
} PVQ_QUEUE;
#endif
typedef struct {
uint8_t *plane[MAX_MB_PLANE];
int stride[MAX_MB_PLANE];
} BUFFER_SET;
#if CONFIG_EXT_INTER
static INLINE int is_inter_singleref_mode(PREDICTION_MODE mode) {
return mode >= NEARESTMV && mode <= NEWFROMNEARMV;
......@@ -884,6 +894,9 @@ void av1_set_contexts(const MACROBLOCKD *xd, struct macroblockd_plane *pd,
#if CONFIG_EXT_INTER
static INLINE int is_interintra_allowed_bsize(const BLOCK_SIZE bsize) {
#if !USE_RECT_INTERINTRA
if (block_size_wide[bsize] != block_size_high[bsize]) return 0;
#endif
// TODO(debargha): Should this be bsize < BLOCK_LARGEST?
return (bsize >= BLOCK_8X8) && (bsize < BLOCK_64X64);
}
......
......@@ -827,54 +827,86 @@ static void build_inter_predictors_for_planes(MACROBLOCKD *xd, BLOCK_SIZE bsize,
}
void av1_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize) {
BUFFER_SET *ctx, BLOCK_SIZE bsize) {
build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0, 0);
#if CONFIG_EXT_INTER
if (is_interintra_pred(&xd->mi[0]->mbmi))
if (is_interintra_pred(&xd->mi[0]->mbmi)) {
BUFFER_SET default_ctx = { { xd->plane[0].dst.buf, NULL, NULL },
{ xd->plane[0].dst.stride, 0, 0 } };
if (!ctx) ctx = &default_ctx;
av1_build_interintra_predictors_sby(xd, xd->plane[0].dst.buf,
xd->plane[0].dst.stride, bsize);
xd->plane[0].dst.stride, ctx, bsize);
}
#else
(void)ctx;
#endif // CONFIG_EXT_INTER
}
void av1_build_inter_predictors_sbp(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize, int plane) {
BUFFER_SET *ctx, BLOCK_SIZE bsize,
int plane) {
build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, plane, plane);
#if CONFIG_EXT_INTER
if (is_interintra_pred(&xd->mi[0]->mbmi)) {
BUFFER_SET default_ctx = {
{ xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
{ xd->plane[0].dst.stride, xd->plane[1].dst.stride,
xd->plane[2].dst.stride }
};
if (!ctx) ctx = &default_ctx;
if (plane == 0) {
av1_build_interintra_predictors_sby(xd, xd->plane[0].dst.buf,
xd->plane[0].dst.stride, bsize);
xd->plane[0].dst.stride, ctx, bsize);
} else {
av1_build_interintra_predictors_sbc(xd, xd->plane[plane].dst.buf,
xd->plane[plane].dst.stride, plane,
bsize);
xd->plane[plane].dst.stride, ctx,
plane, bsize);
}
}
#else
(void)ctx;
#endif // CONFIG_EXT_INTER
}
void av1_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize) {
BUFFER_SET *ctx, BLOCK_SIZE bsize) {
build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 1,
MAX_MB_PLANE - 1);
#if CONFIG_EXT_INTER
if (is_interintra_pred(&xd->mi[0]->mbmi))
if (is_interintra_pred(&xd->mi[0]->mbmi)) {
BUFFER_SET default_ctx = {
{ NULL, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
{ 0, xd->plane[1].dst.stride, xd->plane[2].dst.stride }
};
if (!ctx) ctx = &default_ctx;
av1_build_interintra_predictors_sbuv(
xd, xd->plane[1].dst.buf, xd->plane[2].dst.buf, xd->plane[1].dst.stride,
xd->plane[2].dst.stride, bsize);
xd->plane[2].dst.stride, ctx, bsize);
}
#else
(void)ctx;
#endif // CONFIG_EXT_INTER
}
void av1_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize) {
BUFFER_SET *ctx, BLOCK_SIZE bsize) {
build_inter_predictors_for_planes(xd, bsize, mi_row, mi_col, 0,
MAX_MB_PLANE - 1);
#if CONFIG_EXT_INTER
if (is_interintra_pred(&xd->mi[0]->mbmi))
if (is_interintra_pred(&xd->mi[0]->mbmi)) {
BUFFER_SET default_ctx = {
{ xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf },
{ xd->plane[0].dst.stride, xd->plane[1].dst.stride,
xd->plane[2].dst.stride }
};
if (!ctx) ctx = &default_ctx;
av1_build_interintra_predictors(
xd, xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf,
xd->plane[0].dst.stride, xd->plane[1].dst.stride,
xd->plane[2].dst.stride, bsize);
xd->plane[2].dst.stride, ctx, bsize);
}
#else
(void)ctx;
#endif // CONFIG_EXT_INTER
}
......@@ -1088,11 +1120,15 @@ void av1_build_inter_predictors_sb_sub8x8_extend(MACROBLOCKD *xd,
mi_x, mi_y);
}
#if CONFIG_EXT_INTER
BUFFER_SET ctx = { { xd->plane[0].dst.buf, xd->plane[1].dst.buf,
xd->plane[2].dst.buf },
{ xd->plane[0].dst.stride, xd->plane[1].dst.stride,
xd->plane[2].dst.stride } };
if (is_interintra_pred(&xd->mi[0]->mbmi))
av1_build_interintra_predictors(
xd, xd->plane[0].dst.buf, xd->plane[1].dst.buf, xd->plane[2].dst.buf,
xd->plane[0].dst.stride, xd->plane[1].dst.stride,
xd->plane[2].dst.stride, bsize);
xd->plane[2].dst.stride, &ctx, bsize);
#endif // CONFIG_EXT_INTER
}
......@@ -1845,8 +1881,6 @@ static void combine_interintra_highbd(
}
#endif // CONFIG_AOM_HIGHBITDEPTH
// Break down rectangular intra prediction for joint spatio-temporal prediction
// into two square intra predictions.
static void build_intra_predictors_for_interintra(MACROBLOCKD *xd, uint8_t *ref,
int ref_stride, uint8_t *dst,
int dst_stride,
......@@ -1856,14 +1890,24 @@ static void build_intra_predictors_for_interintra(MACROBLOCKD *xd, uint8_t *ref,
BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, &xd->plane[plane]);
const int bwl = b_width_log2_lookup[plane_bsize];
const int bhl = b_height_log2_lookup[plane_bsize];
TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
#if USE_RECT_INTERINTRA
const int pxbw = 4 << bwl;
const int pxbh = 4 << bhl;
TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
#if CONFIG_AOM_HIGHBITDEPTH
uint16_t tmp16[MAX_SB_SIZE];
#endif
uint8_t tmp[MAX_SB_SIZE];
#endif
if (bwl == bhl) {
av1_predict_intra_block(xd, pd->width, pd->height, max_tx_size, mode, ref,
ref_stride, dst, dst_stride, 0, 0, plane);
#if !USE_RECT_INTERINTRA
} else {
assert(0);
}
#else
} else if (bwl < bhl) {
uint8_t *src_2 = ref + pxbw * ref_stride;
uint8_t *dst_2 = dst + pxbw * dst_stride;
......@@ -1873,15 +1917,28 @@ static void build_intra_predictors_for_interintra(MACROBLOCKD *xd, uint8_t *ref,
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
uint16_t *src_216 = CONVERT_TO_SHORTPTR(src_2);
uint16_t *dst_216 = CONVERT_TO_SHORTPTR(dst_2);
memcpy(tmp16, src_216 - ref_stride, sizeof(*src_216) * pxbw);
memcpy(src_216 - ref_stride, dst_216 - dst_stride,
sizeof(*src_216) * pxbw);
} else
} else {
#endif // CONFIG_AOM_HIGHBITDEPTH
{
memcpy(tmp, src_2 - ref_stride, sizeof(*src_2) * pxbw);
memcpy(src_2 - ref_stride, dst_2 - dst_stride, sizeof(*src_2) * pxbw);
#if CONFIG_AOM_HIGHBITDEPTH
}
#endif
av1_predict_intra_block(xd, pd->width, pd->height, max_tx_size, mode, src_2,
ref_stride, dst_2, dst_stride, 0, 1 << bwl, plane);
#if CONFIG_AOM_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
uint16_t *src_216 = CONVERT_TO_SHORTPTR(src_2);
memcpy(src_216 - ref_stride, tmp16, sizeof(*src_216) * pxbw);
} else {
#endif // CONFIG_AOM_HIGHBITDEPTH
memcpy(src_2 - ref_stride, tmp, sizeof(*src_2) * pxbw);
#if CONFIG_AOM_HIGHBITDEPTH
}
#endif
} else { // bwl > bhl
int i;
uint8_t *src_2 = ref + pxbh;
......@@ -1892,26 +1949,42 @@ static void build_intra_predictors_for_interintra(MACROBLOCKD *xd, uint8_t *ref,
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
uint16_t *src_216 = CONVERT_TO_SHORTPTR(src_2);
uint16_t *dst_216 = CONVERT_TO_SHORTPTR(dst_2);
for (i = 0; i < pxbh; ++i)
for (i = 0; i < pxbh; ++i) {
tmp16[i] = src_216[i * ref_stride - 1];
src_216[i * ref_stride - 1] = dst_216[i * dst_stride - 1];
} else
}
} else {
#endif // CONFIG_AOM_HIGHBITDEPTH
{
for (i = 0; i < pxbh; ++i)
for (i = 0; i < pxbh; ++i) {
tmp[i] = src_2[i * ref_stride - 1];
src_2[i * ref_stride - 1] = dst_2[i * dst_stride - 1];
}
#if CONFIG_AOM_HIGHBITDEPTH
}
#endif
av1_predict_intra_block(xd, pd->width, pd->height, max_tx_size, mode, src_2,
ref_stride, dst_2, dst_stride, 1 << bhl, 0, plane);
#if CONFIG_AOM_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
uint16_t *src_216 = CONVERT_TO_SHORTPTR(src_2);
for (i = 0; i < pxbh; ++i) src_216[i * ref_stride - 1] = tmp16[i];
} else {
#endif // CONFIG_AOM_HIGHBITDEPTH
for (i = 0; i < pxbh; ++i) src_2[i * ref_stride - 1] = tmp[i];
#if CONFIG_AOM_HIGHBITDEPTH
}
#endif
}
#endif
}
void av1_build_intra_predictors_for_interintra(MACROBLOCKD *xd,
BLOCK_SIZE bsize, int plane,
uint8_t *dst, int dst_stride) {
BUFFER_SET *ctx, uint8_t *dst,
int dst_stride) {
build_intra_predictors_for_interintra(
xd, xd->plane[plane].dst.buf, xd->plane[plane].dst.stride, dst,
dst_stride, interintra_to_intra_mode[xd->mi[0]->mbmi.interintra_mode],
bsize, plane);
xd, ctx->plane[plane], ctx->stride[plane], dst, dst_stride,
interintra_to_intra_mode[xd->mi[0]->mbmi.interintra_mode], bsize, plane);
}
void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
......@@ -1938,12 +2011,13 @@ void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
}
void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
int ystride, BLOCK_SIZE bsize) {
int ystride, BUFFER_SET *ctx,
BLOCK_SIZE bsize) {
#if CONFIG_AOM_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
DECLARE_ALIGNED(16, uint16_t, intrapredictor[MAX_SB_SQUARE]);
av1_build_intra_predictors_for_interintra(
xd, bsize, 0, CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE);
xd, bsize, 0, ctx, CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE);
av1_combine_interintra(xd, bsize, 0, ypred, ystride,
CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE);
return;
......@@ -1951,7 +2025,7 @@ void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
#endif // CONFIG_AOM_HIGHBITDEPTH
{
DECLARE_ALIGNED(16, uint8_t, intrapredictor[MAX_SB_SQUARE]);
av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapredictor,
av1_build_intra_predictors_for_interintra(xd, bsize, 0, ctx, intrapredictor,
MAX_SB_SIZE);
av1_combine_interintra(xd, bsize, 0, ypred, ystride, intrapredictor,
MAX_SB_SIZE);
......@@ -1959,13 +2033,14 @@ void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
}
void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred,
int ustride, int plane,
BLOCK_SIZE bsize) {
int ustride, BUFFER_SET *ctx,
int plane, BLOCK_SIZE bsize) {
#if CONFIG_AOM_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
DECLARE_ALIGNED(16, uint16_t, uintrapredictor[MAX_SB_SQUARE]);
av1_build_intra_predictors_for_interintra(
xd, bsize, plane, CONVERT_TO_BYTEPTR(uintrapredictor), MAX_SB_SIZE);
xd, bsize, plane, ctx, CONVERT_TO_BYTEPTR(uintrapredictor),
MAX_SB_SIZE);
av1_combine_interintra(xd, bsize, plane, upred, ustride,
CONVERT_TO_BYTEPTR(uintrapredictor), MAX_SB_SIZE);
return;
......@@ -1973,8 +2048,8 @@ void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred,
#endif // CONFIG_AOM_HIGHBITDEPTH
{
DECLARE_ALIGNED(16, uint8_t, uintrapredictor[MAX_SB_SQUARE]);
av1_build_intra_predictors_for_interintra(xd, bsize, plane, uintrapredictor,
MAX_SB_SIZE);
av1_build_intra_predictors_for_interintra(xd, bsize, plane, ctx,
uintrapredictor, MAX_SB_SIZE);
av1_combine_interintra(xd, bsize, plane, upred, ustride, uintrapredictor,
MAX_SB_SIZE);
}
......@@ -1982,17 +2057,18 @@ void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred,
void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred,
uint8_t *vpred, int ustride,
int vstride, BLOCK_SIZE bsize) {
av1_build_interintra_predictors_sbc(xd, upred, ustride, 1, bsize);
av1_build_interintra_predictors_sbc(xd, vpred, vstride, 2, bsize);
int vstride, BUFFER_SET *ctx,
BLOCK_SIZE bsize) {
av1_build_interintra_predictors_sbc(xd, upred, ustride, ctx, 1, bsize);
av1_build_interintra_predictors_sbc(xd, vpred, vstride, ctx, 2, bsize);
}
void av1_build_interintra_predictors(MACROBLOCKD *xd, uint8_t *ypred,
uint8_t *upred, uint8_t *vpred,
int ystride, int ustride, int vstride,
BLOCK_SIZE bsize) {
av1_build_interintra_predictors_sby(xd, ypred, ystride, bsize);
av1_build_interintra_predictors_sbuv(xd, upred, vpred, ustride, vstride,
BUFFER_SET *ctx, BLOCK_SIZE bsize) {
av1_build_interintra_predictors_sby(xd, ypred, ystride, ctx, bsize);
av1_build_interintra_predictors_sbuv(xd, upred, vpred, ustride, vstride, ctx,
bsize);
}
......
......@@ -333,16 +333,17 @@ void av1_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane, int i, int ir,
int ic, int mi_row, int mi_col);
void av1_build_inter_predictors_sby(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize);
BUFFER_SET *ctx, BLOCK_SIZE bsize);
void av1_build_inter_predictors_sbp(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize, int plane);
BUFFER_SET *ctx, BLOCK_SIZE bsize,
int plane);
void av1_build_inter_predictors_sbuv(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize);
BUFFER_SET *ctx, BLOCK_SIZE bsize);
void av1_build_inter_predictors_sb(MACROBLOCKD *xd, int mi_row, int mi_col,
BLOCK_SIZE bsize);
BUFFER_SET *ctx, BLOCK_SIZE bsize);
#if CONFIG_SUPERTX
void av1_build_inter_predictors_sb_sub8x8_extend(MACROBLOCKD *xd,
......@@ -529,28 +530,26 @@ const uint8_t *av1_get_compound_type_mask(
void av1_build_interintra_predictors(MACROBLOCKD *xd, uint8_t *ypred,
uint8_t *upred, uint8_t *vpred,
int ystride, int ustride, int vstride,
BLOCK_SIZE bsize);
BUFFER_SET *ctx, BLOCK_SIZE bsize);
void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
int ystride, BLOCK_SIZE bsize);
void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred,
int ustride, int plane,
int ystride, BUFFER_SET *ctx,
BLOCK_SIZE bsize);
void av1_build_interintra_predictors_sbc(MACROBLOCKD *xd, uint8_t *upred,
int ustride, BUFFER_SET *ctx,
int plane, BLOCK_SIZE bsize);
void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred,
uint8_t *vpred, int ustride,
int vstride, BLOCK_SIZE bsize);
int vstride, BUFFER_SET *ctx,
BLOCK_SIZE bsize);
void av1_build_intra_predictors_for_interintra(MACROBLOCKD *xd,
BLOCK_SIZE bsize, int plane,
BUFFER_SET *ctx,
uint8_t *intra_pred,
int intra_stride);
void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
const uint8_t *inter_pred, int inter_stride,
const uint8_t *intra_pred, int intra_stride);
void av1_build_interintra_predictors_sbuv(MACROBLOCKD *xd, uint8_t *upred,
uint8_t *vpred, int ustride,
int vstride, BLOCK_SIZE bsize);
void av1_build_interintra_predictors_sby(MACROBLOCKD *xd, uint8_t *ypred,
int ystride, BLOCK_SIZE bsize);
// Encoder only
void av1_build_inter_predictors_for_planes_single_buf(
......
......@@ -1502,7 +1502,7 @@ static void decode_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
}
} else {
// Prediction
av1_build_inter_predictors_sb(xd, mi_row, mi_col,
av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL,
AOMMAX(bsize, BLOCK_8X8));
// Reconstruction
......@@ -1601,7 +1601,7 @@ static void decode_block(AV1Decoder *const pbi, MACROBLOCKD *const xd,
}
} else {
#endif // CONFIG_WARPED_MOTION
av1_build_inter_predictors_sb(xd, mi_row, mi_col,
av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL,
AOMMAX(bsize, BLOCK_8X8));
#if CONFIG_WARPED_MOTION
}
......
......@@ -919,7 +919,7 @@ static void choose_partitioning(AV1_COMP *const cpi, ThreadData *const td,
x->pred_mv[LAST_FRAME] = mbmi->mv[0].as_mv;
}
av1_build_inter_predictors_sb(xd, mi_row, mi_col, cm->sb_size);
av1_build_inter_predictors_sb(xd, mi_row, mi_col, NULL, cm->sb_size);
ref = xd->plane[0].dst.buf;
ref_stride = xd->plane[0].dst.stride;
......@@ -5550,10 +5550,10 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
} else {
#endif // CONFIG_WARPED_MOTION
if (!(cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready) || seg_skip)
av1_build_inter_predictors_sby(xd, mi_row, mi_col,
av1_build_inter_predictors_sby(xd, mi_row, mi_col, NULL,
AOMMAX(bsize, BLOCK_8X8));
av1_build_inter_predictors_sbuv(xd, mi_row, mi_col,
av1_build_inter_predictors_sbuv(xd, mi_row, mi_col, NULL,
AOMMAX(bsize, BLOCK_8X8));
#if CONFIG_WARPED_MOTION
}
......
......@@ -853,7 +853,8 @@ void av1_first_pass(AV1_COMP *cpi, const struct lookahead_entry *source) {
xd->mi[0]->mbmi.tx_size = TX_4X4;
xd->mi[0]->mbmi.ref_frame[0] = LAST_FRAME;
xd->mi[0]->mbmi.ref_frame[1] = NONE;
av1_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, bsize);
av1_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, NULL,
bsize);
av1_encode_sby_pass1(cm, x, bsize);
sum_mvr += mv.row;
sum_mvr_abs += abs(mv.row);
......
......@@ -74,7 +74,7 @@ static unsigned int do_16x16_motion_iteration(AV1_COMP *cpi, const MV *ref_mv,
xd->mi[0]->mbmi.ref_frame[1] = NONE;
#endif // CONFIG_EXT_INTER
av1_build_inter_predictors_sby(xd, mb_row, mb_col, BLOCK_16X16);
av1_build_inter_predictors_sby(xd, mb_row, mb_col, NULL, BLOCK_16X16);
/* restore UMV window */
x->mv_col_min = tmp_col_min;
......
......@@ -6371,13 +6371,11 @@ static void single_motion_search(const AV1_COMP *const cpi, MACROBLOCK *x,
}
}
static INLINE void restore_dst_buf(MACROBLOCKD *xd,
uint8_t *orig_dst[MAX_MB_PLANE],
int orig_dst_stride[MAX_MB_PLANE]) {
static INLINE void restore_dst_buf(MACROBLOCKD *xd, BUFFER_SET dst) {
int i;
for (i = 0; i < MAX_MB_PLANE; i++) {
xd->plane[i].dst.buf = orig_dst[i];
xd->plane[i].dst.stride = orig_dst_stride[i];
xd->plane[i].dst.buf = dst.plane[i];
xd->plane[i].dst.stride = dst.stride[i];
}
}
......@@ -6934,8 +6932,8 @@ static int interinter_compound_motion_search(const AV1_COMP *const cpi,
static int64_t build_and_cost_compound_wedge(
const AV1_COMP *const cpi, MACROBLOCK *x, const int_mv *const cur_mv,
const BLOCK_SIZE bsize, const int this_mode, int rs2, int rate_mv,
int *out_rate_mv, uint8_t **preds0, uint8_t **preds1, int *strides,
int mi_row, int mi_col) {
BUFFER_SET *ctx, int *out_rate_mv, uint8_t **preds0, uint8_t **preds1,
int *strides, int mi_row, int mi_col) {
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
int rate_sum;
......@@ -6951,7 +6949,7 @@ static int64_t build_and_cost_compound_wedge(
if (have_newmv_in_inter_mode(this_mode)) {
*out_rate_mv = interinter_compound_motion_search(cpi, x, bsize, this_mode,
mi_row, mi_col);
av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
av1_build_inter_predictors_sby(xd, mi_row, mi_col, ctx, bsize);
model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
&tmp_skip_txfm_sb, &tmp_skip_sse_sb);
rd = RDCOST(x->rdmult, x->rddiv, rs2 + *out_rate_mv + rate_sum, dist_sum);
......@@ -7056,10 +7054,7 @@ static int64_t handle_inter_mode(
double pts[144], pts_inref[144];
#endif // CONFIG_WARPED_MOTION
int64_t rd = INT64_MAX;
uint8_t *orig_dst[MAX_MB_PLANE];
int orig_dst_stride[MAX_MB_PLANE];
uint8_t *tmp_dst[MAX_MB_PLANE];
int tmp_dst_stride[MAX_MB_PLANE];
BUFFER_SET orig_dst, tmp_dst;
int rs = 0;
InterpFilter assign_filter = SWITCHABLE;
......@@ -7312,12 +7307,12 @@ static int64_t handle_inter_mode(
// one for future predictions. In the end, copy from tmp_buf to
// dst if necessary.
for (i = 0; i < MAX_MB_PLANE; i++) {
tmp_dst[i] = tmp_buf + i * MAX_SB_SQUARE;
tmp_dst_stride[i] = MAX_SB_SIZE;
tmp_dst.plane[i] = tmp_buf + i * MAX_SB_SQUARE;
tmp_dst.stride[i] = MAX_SB_SIZE;
}
for (i = 0; i < MAX_MB_PLANE; i++) {
orig_dst[i] = xd->plane[i].dst.buf;
orig_dst_stride[i] = xd->plane[i].dst.stride;
orig_dst.plane[i] = xd->plane[i].dst.buf;
orig_dst.stride[i] = xd->plane[i].dst.stride;
}
// We don't include the cost of the second reference here, because there
......@@ -7383,7 +7378,7 @@ static int64_t handle_inter_mode(
assign_filter == SWITCHABLE ? EIGHTTAP_REGULAR : assign_filter;
#endif
rs = av1_get_switchable_rate(cpi, xd);
av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
&tmp_dist, &skip_txfm_sb, &skip_sse_sb);
rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
......@@ -7403,7 +7398,7 @@ static int64_t handle_inter_mode(
#else
InterpFilter best_filter = mbmi->interp_filter;
#endif
restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
restore_dst_buf(xd, tmp_dst);
// EIGHTTAP_REGULAR mode is calculated beforehand
for (i = 1; i < filter_set_size; ++i) {
int tmp_skip_sb = 0;
......@@ -7419,7 +7414,7 @@ static int64_t handle_inter_mode(
mbmi->interp_filter = i;
#endif
tmp_rs = av1_get_switchable_rate(cpi, xd);
av1_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
av1_build_inter_predictors_sb(xd, mi_row, mi_col, &orig_dst, bsize);
model_rd_for_sb(cpi, bsize, x, xd, 0, MAX_MB_PLANE - 1, &tmp_rate,
&tmp_dist, &tmp_skip_sb, &tmp_skip_sse);
tmp_rd = RDCOST(x->rdmult, x->rddiv, tmp_rs + tmp_rate, tmp_dist);
......@@ -7436,16 +7431,16 @@ static int64_t handle_inter_mode(
skip_sse_sb = tmp_skip_sse;
best_in_temp = !best_in_temp;
if (best_in_temp) {
restore_dst_buf(xd, orig_dst, orig_dst_stride);
restore_dst_buf(xd, orig_dst);
} else {
restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
restore_dst_buf(xd, tmp_dst);
}
}
}
if (best_in_temp) {
restore_dst_buf(xd, tmp_dst, tmp_dst_stride);
restore_dst_buf(xd, tmp_dst);
} else {
restore_dst_buf(xd, orig_dst, orig_dst_stride);
restore_dst_buf(xd, orig_dst);
}
#if CONFIG_DUAL_FILTER
av1_copy(mbmi->interp_filter, best_filter);
......@@ -7523,7 +7518,7 @@ static int64_t handle_inter_mode(
switch (cur_type) {
case COMPOUND_AVERAGE:
av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
av1_subtract_plane(x, bsize, 0);
rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
&tmp_skip_txfm_sb, &tmp_skip_sse_sb,
......@@ -7539,8 +7534,8 @@ static int64_t handle_inter_mode(
best_rd_compound / 3 < ref_best_rd) {
int tmp_rate_mv = 0;
best_rd_cur = build_and_cost_compound_wedge(
cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &tmp_rate_mv,
preds0, preds1, strides, mi_row, mi_col);
cpi, x, cur_mv, bsize, this_mode, rs2, rate_mv, &orig_dst,
&tmp_rate_mv, preds0, preds1, strides, mi_row, mi_col);
if (best_rd_cur < best_rd_compound) {
best_rd_compound = best_rd_cur;
......@@ -7574,7 +7569,7 @@ static int64_t handle_inter_mode(
}
if (ref_best_rd < INT64_MAX && best_rd_compound / 3 > ref_best_rd) {
restore_dst_buf(xd, orig_dst, orig_dst_stride);
restore_dst_buf(xd, orig_dst);
return INT64_MAX;
}
......@@ -7614,15 +7609,16 @@ static int64_t handle_inter_mode(
xd->plane[j].dst.buf = tmp_buf + j * MAX_SB_SQUARE;
xd->plane[j].dst.stride = bw;
}
av1_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
restore_dst_buf(xd, orig_dst, orig_dst_stride);
av1_build_inter_predictors_sby(xd, mi_row, mi_col, &orig_dst, bsize);
restore_dst_buf(xd, orig_dst);
mbmi->ref_frame[1] = INTRA_FRAME;
mbmi->use_wedge_interintra = 0;
for (j = 0; j < INTERINTRA_MODES; ++j) {
mbmi->interintra_mode = (INTERINTRA_MODE)j;
rmode = interintra_mode_cost[mbmi->interintra_mode];
av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
intrapred, bw);
av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
model_rd_for_sb(cpi, bsize, x, xd, 0, 0, &rate_sum, &dist_sum,
&tmp_skip_txfm_sb, &tmp_skip_sse_sb);
......@@ -7634,7 +7630,8 @@ static int64_t handle_inter_mode(
}
mbmi->interintra_mode = best_interintra_mode;
rmode = interintra_mode_cost[mbmi->interintra_mode];
av1_build_intra_predictors_for_interintra(xd, bsize, 0, intrapred, bw);
av1_build_intra_predictors_for_interintra(xd, bsize, 0, &orig_dst,
intrapred, bw);
av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
av1_subtract_plane(x, bsize, 0);
rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
......@@ -7674,7 +7671,7 @@ static int64_t handle_inter_mode(
do_masked_motion_search(cpi, x, mask, bw, bsize, mi_row, mi_col,
&tmp_mv, &tmp_rate_mv, 0, mv_idx);
mbmi->mv[0].as_int = tmp_mv.as_int;