Commit 370f203a authored by Yue Chen's avatar Yue Chen

Add single motion search for OBMC predictor

Weighted single motion search is implemented for obmc predictor.
When NEWMV mode is used, to determine the MV for the current block,
we run weighted motion search to compare the weighted prediction
with (source - weighted prediction using neighbors' MVs), in which
the distortion is the actual prediction error of obmc prediction.

Coding gain: 0.404/0.425/0.366 for lowres/midres/hdres
Speed impact: +14% encoding time
              (obmc w/o mv search 13%-> obmc w/ mv search 27%)

Change-Id: Id7ad3fc6ba295b23d9c53c8a16a4ac1677ad835c
parent 1d2d1e75
......@@ -462,6 +462,7 @@ static INLINE int vp10_is_interp_needed(const MACROBLOCKD *const xd) {
#endif // CONFIG_EXT_INTERP
#if CONFIG_OBMC
void setup_obmc_mask(int length, const uint8_t *mask[2]);
void vp10_build_obmc_inter_prediction(VP10_COMMON *cm,
MACROBLOCKD *xd, int mi_row, int mi_col,
int use_tmp_dst_buf,
......
This diff is collapsed.
This diff is collapsed.
......@@ -195,6 +195,29 @@ int vp10_masked_full_pixel_diamond(const struct VP10_COMP *cpi, MACROBLOCK *x,
const MV *ref_mv, MV *dst_mv,
int is_second);
#endif // CONFIG_EXT_INTER
#if CONFIG_OBMC
int vp10_obmc_full_pixel_diamond(const struct VP10_COMP *cpi, MACROBLOCK *x,
const int *wsrc, int wsrc_stride,
const int *mask, int mask_stride,
MV *mvp_full, int step_param,
int sadpb, int further_steps, int do_refine,
const vp10_variance_fn_ptr_t *fn_ptr,
const MV *ref_mv, MV *dst_mv,
int is_second);
int vp10_find_best_obmc_sub_pixel_tree_up(struct VP10_COMP *cpi, MACROBLOCK *x,
const int *wsrc, int wsrc_stride,
const int *mask, int mask_stride,
int mi_row, int mi_col,
MV *bestmv, const MV *ref_mv,
int allow_hp, int error_per_bit,
const vp10_variance_fn_ptr_t *vfp,
int forced_stop, int iters_per_step,
int *mvjcost, int *mvcost[2],
int *distortion, unsigned int *sse1,
int is_second,
int use_upsampled_ref);
#endif // CONFIG_OBMC
#ifdef __cplusplus
} // extern "C"
#endif
......
This diff is collapsed.
......@@ -108,6 +108,17 @@ static INLINE const YV12_BUFFER_CONFIG *get_upsampled_ref(VP10_COMP *cpi,
return &cpi->upsampled_ref_bufs[cpi->upsampled_ref_idx[ref_idx]].buf;
}
#if CONFIG_OBMC
void calc_target_weighted_pred(VP10_COMMON *cm,
MACROBLOCK *x,
MACROBLOCKD *xd,
int mi_row, int mi_col,
uint8_t *above_buf, int above_stride,
uint8_t *left_buf, int left_stride,
int *mask_buf, int mask_stride,
int *weighted_src_buf, int weighted_src_stride);
#endif // CONFIG_OBMC
#ifdef __cplusplus
} // extern "C"
#endif
......
......@@ -450,3 +450,109 @@ HIGHBD_MASKSADMXN(4, 8)
HIGHBD_MASKSADMXN(4, 4)
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // CONFIG_VP10 && CONFIG_EXT_INTER
#if CONFIG_VP10 && CONFIG_OBMC
// a: pred
// b: target weighted prediction (has been *4096 to keep precision)
// m: 2d weights (scaled by 4096)
static INLINE unsigned int obmc_sad(const uint8_t *a, int a_stride,
const int *b, int b_stride,
const int *m, int m_stride,
int width, int height) {
int y, x;
unsigned int sad = 0;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
int abs_diff = abs(b[x] - a[x] * m[x]);
sad += (abs_diff + 2048) >> 12;
}
a += a_stride;
b += b_stride;
m += m_stride;
}
return sad;
}
#define OBMCSADMxN(m, n) \
unsigned int vpx_obmc_sad##m##x##n##_c(const uint8_t *ref, int ref_stride, \
const int *wsrc, int wsrc_stride, \
const int *msk, int msk_stride) { \
return obmc_sad(ref, ref_stride, wsrc, wsrc_stride, msk, msk_stride, m, n); \
}
#if CONFIG_EXT_PARTITION
OBMCSADMxN(128, 128)
OBMCSADMxN(128, 64)
OBMCSADMxN(64, 128)
#endif // CONFIG_EXT_PARTITION
OBMCSADMxN(64, 64)
OBMCSADMxN(64, 32)
OBMCSADMxN(32, 64)
OBMCSADMxN(32, 32)
OBMCSADMxN(32, 16)
OBMCSADMxN(16, 32)
OBMCSADMxN(16, 16)
OBMCSADMxN(16, 8)
OBMCSADMxN(8, 16)
OBMCSADMxN(8, 8)
OBMCSADMxN(8, 4)
OBMCSADMxN(4, 8)
OBMCSADMxN(4, 4)
#if CONFIG_VP9_HIGHBITDEPTH
static INLINE unsigned int highbd_obmc_sad(const uint8_t *a8, int a_stride,
const int *b, int b_stride,
const int *m, int m_stride,
int width, int height) {
int y, x;
unsigned int sad = 0;
const uint16_t *a = CONVERT_TO_SHORTPTR(a8);
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
int abs_diff = abs(b[x] - a[x] * m[x]);
sad += (abs_diff + 2048) >> 12;
}
a += a_stride;
b += b_stride;
m += m_stride;
}
return sad;
}
#define HIGHBD_OBMCSADMXN(m, n) \
unsigned int vpx_highbd_obmc_sad##m##x##n##_c(const uint8_t *ref, \
int ref_stride, \
const int *wsrc, \
int wsrc_stride, \
const int *msk, \
int msk_stride) { \
return highbd_obmc_sad(ref, ref_stride, wsrc, wsrc_stride, \
msk, msk_stride, m, n); \
}
#if CONFIG_EXT_PARTITION
HIGHBD_OBMCSADMXN(128, 128)
HIGHBD_OBMCSADMXN(128, 64)
HIGHBD_OBMCSADMXN(64, 128)
#endif // CONFIG_EXT_PARTITION
HIGHBD_OBMCSADMXN(64, 64)
HIGHBD_OBMCSADMXN(64, 32)
HIGHBD_OBMCSADMXN(32, 64)
HIGHBD_OBMCSADMXN(32, 32)
HIGHBD_OBMCSADMXN(32, 16)
HIGHBD_OBMCSADMXN(16, 32)
HIGHBD_OBMCSADMXN(16, 16)
HIGHBD_OBMCSADMXN(16, 8)
HIGHBD_OBMCSADMXN(8, 16)
HIGHBD_OBMCSADMXN(8, 8)
HIGHBD_OBMCSADMXN(8, 4)
HIGHBD_OBMCSADMXN(4, 8)
HIGHBD_OBMCSADMXN(4, 4)
#endif // CONFIG_VP9_HIGHBITDEPTH
#endif // CONFIG_VP10 && CONFIG_OBMC
This diff is collapsed.
......@@ -98,6 +98,30 @@ typedef unsigned int (*vpx_masked_subpixvariance_fn_t)(const uint8_t *src,
unsigned int *sse);
#endif // CONFIG_VP10 && CONFIG_EXT_INTER
#if CONFIG_VP10 && CONFIG_OBMC
typedef unsigned int(*vpx_obmc_sad_fn_t)(const uint8_t *pred,
int pred_stride,
const int *wsrc,
int wsrc_stride,
const int *msk,
int msk_stride);
typedef unsigned int (*vpx_obmc_variance_fn_t)(const uint8_t *pred,
int pred_stride,
const int *wsrc,
int wsrc_stride,
const int *msk,
int msk_stride,
unsigned int *sse);
typedef unsigned int (*vpx_obmc_subpixvariance_fn_t)(const uint8_t *pred,
int pred_stride,
int xoffset, int yoffset,
const int *wsrc,
int wsrc_stride,
const int *msk,
int msk_stride,
unsigned int *sse);
#endif // CONFIG_VP10 && CONFIG_OBMC
#if CONFIG_VP9
typedef struct vp9_variance_vtable {
vpx_sad_fn_t sdf;
......@@ -126,6 +150,11 @@ typedef struct vp10_variance_vtable {
vpx_masked_variance_fn_t mvf;
vpx_masked_subpixvariance_fn_t msvf;
#endif // CONFIG_EXT_INTER
#if CONFIG_OBMC
vpx_obmc_sad_fn_t osdf;
vpx_obmc_variance_fn_t ovf;
vpx_obmc_subpixvariance_fn_t osvf;
#endif // CONFIG_OBMC
} vp10_variance_fn_ptr_t;
#endif // CONFIG_VP10
......
......@@ -1094,6 +1094,25 @@ if (vpx_config("CONFIG_EXT_INTER") eq "yes") {
}
}
#
# OBMC SAD
#
if (vpx_config("CONFIG_OBMC") eq "yes") {
foreach (@block_sizes) {
($w, $h) = @$_;
add_proto qw/unsigned int/, "vpx_obmc_sad${w}x${h}", "const uint8_t *ref_ptr, int ref_stride, const int *wsrc_ptr, int wsrc_stride, const int *mask, int mask_stride";
specialize "vpx_obmc_sad${w}x${h}";
}
if (vpx_config("CONFIG_VP9_HIGHBITDEPTH") eq "yes") {
foreach (@block_sizes) {
($w, $h) = @$_;
add_proto qw/unsigned int/, "vpx_highbd_obmc_sad${w}x${h}", "const uint8_t *ref_ptr, int ref_stride, const int *wsrc_ptr, int wsrc_stride, const int *mask, int mask_stride";
specialize "vpx_highbd_obmc_sad${w}x${h}";
}
}
}
#
# Multi-block SAD, comparing a reference to N blocks 1 pixel apart horizontally
#
......@@ -1364,6 +1383,31 @@ if (vpx_config("CONFIG_EXT_INTER") eq "yes") {
}
}
#
# OBMC Variance / OBMC Subpixel Variance
#
if (vpx_config("CONFIG_OBMC") eq "yes") {
foreach (@block_sizes) {
($w, $h) = @$_;
add_proto qw/unsigned int/, "vpx_obmc_variance${w}x${h}", "const uint8_t *pre_ptr, int pre_stride, const int *wsrc_ptr, int wsrc_stride, const int *mask, int mask_stride, unsigned int *sse";
add_proto qw/unsigned int/, "vpx_obmc_sub_pixel_variance${w}x${h}", "const uint8_t *pre_ptr, int pre_stride, int xoffset, int yoffset, const int *wsrc_ptr, int wsrc_stride, const int *mask, int mask_stride, unsigned int *sse";
specialize "vpx_obmc_variance${w}x${h}";
specialize "vpx_obmc_sub_pixel_variance${w}x${h}";
}
if (vpx_config("CONFIG_VP9_HIGHBITDEPTH") eq "yes") {
foreach $bd ("_", "_10_", "_12_") {
foreach (@block_sizes) {
($w, $h) = @$_;
add_proto qw/unsigned int/, "vpx_highbd${bd}obmc_variance${w}x${h}", "const uint8_t *pre_ptr, int pre_stride, const int *wsrc_ptr, int wsrc_stride, const int *mask, int mask_stride, unsigned int *sse";
add_proto qw/unsigned int/, "vpx_highbd${bd}obmc_sub_pixel_variance${w}x${h}", "const uint8_t *pre_ptr, int pre_stride, int xoffset, int yoffset, const int *wsrc_ptr, int wsrc_stride, const int *mask, int mask_stride, unsigned int *sse";
specialize "vpx_highbd${bd}obmc_variance${w}x${h}";
specialize "vpx_highbd${bd}obmc_sub_pixel_variance${w}x${h}";
}
}
}
}
#
# Specialty Subpixel
#
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment