Dual prediction filter type for motion compensated reference
Make the bit-stream level support per direction filter type coding for motion compensated reference. Change-Id: I61a2360b301075f6734cfd9711b7ae68f214174d
This commit is contained in:
Родитель
7c5fd6aadc
Коммит
bd33326372
|
@ -12,9 +12,18 @@ using libvpx_test::ACMRandom;
|
|||
namespace {
|
||||
TEST(VP10ConvolveTest, vp10_convolve8) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
#if CONFIG_DUAL_FILTER
|
||||
INTERP_FILTER interp_filter[4] = {
|
||||
EIGHTTAP_REGULAR, EIGHTTAP_REGULAR,
|
||||
EIGHTTAP_REGULAR, EIGHTTAP_REGULAR
|
||||
};
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter[0]);
|
||||
#else
|
||||
INTERP_FILTER interp_filter = EIGHTTAP_REGULAR;
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter);
|
||||
#endif
|
||||
ptrdiff_t filter_size = filter_params.taps;
|
||||
int filter_center = filter_size / 2 - 1;
|
||||
uint8_t src[12 * 12];
|
||||
|
@ -36,7 +45,7 @@ TEST(VP10ConvolveTest, vp10_convolve8) {
|
|||
}
|
||||
|
||||
vp10_convolve(src + src_stride * filter_center + filter_center, src_stride,
|
||||
dst, dst_stride, w, h, filter_params, subpel_x_q4, x_step_q4,
|
||||
dst, dst_stride, w, h, interp_filter, subpel_x_q4, x_step_q4,
|
||||
subpel_y_q4, y_step_q4, avg);
|
||||
|
||||
const int16_t* x_filter =
|
||||
|
@ -50,9 +59,18 @@ TEST(VP10ConvolveTest, vp10_convolve8) {
|
|||
}
|
||||
TEST(VP10ConvolveTest, vp10_convolve) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
#if CONFIG_DUAL_FILTER
|
||||
INTERP_FILTER interp_filter[4] = {
|
||||
EIGHTTAP_REGULAR, EIGHTTAP_REGULAR,
|
||||
EIGHTTAP_REGULAR, EIGHTTAP_REGULAR
|
||||
};
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter[0]);
|
||||
#else
|
||||
INTERP_FILTER interp_filter = EIGHTTAP_REGULAR;
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter);
|
||||
#endif
|
||||
ptrdiff_t filter_size = filter_params.taps;
|
||||
int filter_center = filter_size / 2 - 1;
|
||||
uint8_t src[12 * 12];
|
||||
|
@ -75,7 +93,7 @@ TEST(VP10ConvolveTest, vp10_convolve) {
|
|||
for (subpel_x_q4 = 0; subpel_x_q4 < 16; subpel_x_q4++) {
|
||||
for (subpel_y_q4 = 0; subpel_y_q4 < 16; subpel_y_q4++) {
|
||||
vp10_convolve(src + src_stride * filter_center + filter_center,
|
||||
src_stride, dst, dst_stride, w, h, filter_params,
|
||||
src_stride, dst, dst_stride, w, h, interp_filter,
|
||||
subpel_x_q4, x_step_q4, subpel_y_q4, y_step_q4, avg);
|
||||
|
||||
const int16_t* x_filter =
|
||||
|
@ -101,9 +119,18 @@ TEST(VP10ConvolveTest, vp10_convolve) {
|
|||
|
||||
TEST(VP10ConvolveTest, vp10_convolve_avg) {
|
||||
ACMRandom rnd(ACMRandom::DeterministicSeed());
|
||||
#if CONFIG_DUAL_FILTER
|
||||
INTERP_FILTER interp_filter[4] = {
|
||||
EIGHTTAP_REGULAR, EIGHTTAP_REGULAR,
|
||||
EIGHTTAP_REGULAR, EIGHTTAP_REGULAR
|
||||
};
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter[0]);
|
||||
#else
|
||||
INTERP_FILTER interp_filter = EIGHTTAP_REGULAR;
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter);
|
||||
#endif
|
||||
ptrdiff_t filter_size = filter_params.taps;
|
||||
int filter_center = filter_size / 2 - 1;
|
||||
uint8_t src0[12 * 12];
|
||||
|
@ -134,20 +161,20 @@ TEST(VP10ConvolveTest, vp10_convolve_avg) {
|
|||
for (subpel_y_q4 = 0; subpel_y_q4 < 16; subpel_y_q4++) {
|
||||
avg = 0;
|
||||
vp10_convolve(src0 + offset, src_stride, dst0, dst_stride, w, h,
|
||||
filter_params, subpel_x_q4, x_step_q4, subpel_y_q4,
|
||||
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
||||
y_step_q4, avg);
|
||||
avg = 0;
|
||||
vp10_convolve(src1 + offset, src_stride, dst1, dst_stride, w, h,
|
||||
filter_params, subpel_x_q4, x_step_q4, subpel_y_q4,
|
||||
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
||||
y_step_q4, avg);
|
||||
|
||||
avg = 0;
|
||||
vp10_convolve(src0 + offset, src_stride, dst, dst_stride, w, h,
|
||||
filter_params, subpel_x_q4, x_step_q4, subpel_y_q4,
|
||||
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
||||
y_step_q4, avg);
|
||||
avg = 1;
|
||||
vp10_convolve(src1 + offset, src_stride, dst, dst_stride, w, h,
|
||||
filter_params, subpel_x_q4, x_step_q4, subpel_y_q4,
|
||||
interp_filter, subpel_x_q4, x_step_q4, subpel_y_q4,
|
||||
y_step_q4, avg);
|
||||
|
||||
EXPECT_EQ(dst[0], ROUND_POWER_OF_TWO(dst0[0] + dst1[0], 1));
|
||||
|
|
|
@ -198,7 +198,11 @@ typedef struct {
|
|||
PALETTE_MODE_INFO palette_mode_info;
|
||||
|
||||
// Only for INTER blocks
|
||||
#if CONFIG_DUAL_FILTER
|
||||
INTERP_FILTER interp_filter[4];
|
||||
#else
|
||||
INTERP_FILTER interp_filter;
|
||||
#endif
|
||||
MV_REFERENCE_FRAME ref_frame[2];
|
||||
TX_TYPE tx_type;
|
||||
|
||||
|
|
|
@ -14,6 +14,44 @@
|
|||
#include "vp10/common/seg_common.h"
|
||||
|
||||
// Returns a context number for the given MB prediction signal
|
||||
#if CONFIG_DUAL_FILTER
|
||||
int vp10_get_pred_context_switchable_interp(const MACROBLOCKD *xd, int dir) {
|
||||
const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
|
||||
MV_REFERENCE_FRAME ref_frame = (dir < 2) ?
|
||||
mbmi->ref_frame[0] : mbmi->ref_frame[1];
|
||||
// Note:
|
||||
// The mode info data structure has a one element border above and to the
|
||||
// left of the entries corresponding to real macroblocks.
|
||||
// The prediction flags in these dummy entries are initialized to 0.
|
||||
const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
|
||||
const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
|
||||
int left_type = SWITCHABLE_FILTERS;
|
||||
int above_type = SWITCHABLE_FILTERS;
|
||||
|
||||
if (xd->left_available) {
|
||||
if (left_mbmi->ref_frame[0] == ref_frame)
|
||||
left_type = left_mbmi->interp_filter[(dir & 0x01)];
|
||||
else if (left_mbmi->ref_frame[1] == ref_frame)
|
||||
left_type = left_mbmi->interp_filter[(dir & 0x01) + 2];
|
||||
}
|
||||
|
||||
if (xd->up_available) {
|
||||
if (above_mbmi->ref_frame[0] == ref_frame)
|
||||
above_type = above_mbmi->interp_filter[(dir & 0x01)];
|
||||
else if (above_mbmi->ref_frame[1] == ref_frame)
|
||||
above_type = above_mbmi->interp_filter[(dir & 0x01) + 2];
|
||||
}
|
||||
|
||||
if (left_type == above_type)
|
||||
return left_type;
|
||||
else if (left_type == SWITCHABLE_FILTERS && above_type != SWITCHABLE_FILTERS)
|
||||
return above_type;
|
||||
else if (left_type != SWITCHABLE_FILTERS && above_type == SWITCHABLE_FILTERS)
|
||||
return left_type;
|
||||
else
|
||||
return SWITCHABLE_FILTERS;
|
||||
}
|
||||
#else
|
||||
int vp10_get_pred_context_switchable_interp(const MACROBLOCKD *xd) {
|
||||
// Note:
|
||||
// The mode info data structure has a one element border above and to the
|
||||
|
@ -35,6 +73,7 @@ int vp10_get_pred_context_switchable_interp(const MACROBLOCKD *xd) {
|
|||
else
|
||||
return SWITCHABLE_FILTERS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXT_INTRA
|
||||
// Obtain the reference filter type from the above/left neighbor blocks.
|
||||
|
@ -44,7 +83,11 @@ static INTRA_FILTER get_ref_intra_filter(const MB_MODE_INFO *ref_mbmi) {
|
|||
if (ref_mbmi->sb_type >= BLOCK_8X8) {
|
||||
PREDICTION_MODE mode = ref_mbmi->mode;
|
||||
if (is_inter_block(ref_mbmi)) {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
switch (ref_mbmi->interp_filter[0]) {
|
||||
#else
|
||||
switch (ref_mbmi->interp_filter) {
|
||||
#endif
|
||||
case EIGHTTAP_REGULAR:
|
||||
ref_type = INTRA_FILTER_8TAP;
|
||||
break;
|
||||
|
|
|
@ -66,7 +66,11 @@ static INLINE vpx_prob vp10_get_skip_prob(const VP10_COMMON *cm,
|
|||
return cm->fc->skip_probs[vp10_get_skip_context(xd)];
|
||||
}
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
int vp10_get_pred_context_switchable_interp(const MACROBLOCKD *xd, int dir);
|
||||
#else
|
||||
int vp10_get_pred_context_switchable_interp(const MACROBLOCKD *xd);
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXT_INTRA
|
||||
int vp10_get_pred_context_intra_interp(const MACROBLOCKD *xd);
|
||||
|
|
|
@ -461,7 +461,11 @@ void vp10_make_masked_inter_predictor(
|
|||
const int subpel_y,
|
||||
const struct scale_factors *sf,
|
||||
int w, int h,
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const INTERP_FILTER *interp_filter,
|
||||
#else
|
||||
const INTERP_FILTER interp_filter,
|
||||
#endif
|
||||
int xs, int ys,
|
||||
#if CONFIG_SUPERTX
|
||||
int wedge_offset_x, int wedge_offset_y,
|
||||
|
@ -557,7 +561,11 @@ void vp10_build_inter_predictor(const uint8_t *src, int src_stride,
|
|||
const MV *src_mv,
|
||||
const struct scale_factors *sf,
|
||||
int w, int h, int ref,
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const INTERP_FILTER *interp_filter,
|
||||
#else
|
||||
const INTERP_FILTER interp_filter,
|
||||
#endif
|
||||
enum mv_precision precision,
|
||||
int x, int y) {
|
||||
const int is_q4 = precision == MV_PRECISION_Q4;
|
||||
|
@ -591,7 +599,6 @@ void build_inter_predictors(MACROBLOCKD *xd, int plane,
|
|||
const MODE_INFO *mi = xd->mi[0];
|
||||
#endif // CONFIG_OBMC
|
||||
const int is_compound = has_second_ref(&mi->mbmi);
|
||||
const INTERP_FILTER interp_filter = mi->mbmi.interp_filter;
|
||||
int ref;
|
||||
|
||||
for (ref = 0; ref < 1 + is_compound; ++ref) {
|
||||
|
@ -640,7 +647,7 @@ void build_inter_predictors(MACROBLOCKD *xd, int plane,
|
|||
vp10_make_masked_inter_predictor(
|
||||
pre, pre_buf->stride, dst, dst_buf->stride,
|
||||
subpel_x, subpel_y, sf, w, h,
|
||||
interp_filter, xs, ys,
|
||||
mi->mbmi.interp_filter, xs, ys,
|
||||
#if CONFIG_SUPERTX
|
||||
wedge_offset_x, wedge_offset_y,
|
||||
#endif // CONFIG_SUPERTX
|
||||
|
@ -649,7 +656,7 @@ void build_inter_predictors(MACROBLOCKD *xd, int plane,
|
|||
#endif // CONFIG_EXT_INTER
|
||||
vp10_make_inter_predictor(pre, pre_buf->stride, dst, dst_buf->stride,
|
||||
subpel_x, subpel_y, sf, w, h, ref,
|
||||
interp_filter, xs, ys, xd);
|
||||
mi->mbmi.interp_filter, xs, ys, xd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -665,7 +672,6 @@ void vp10_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane,
|
|||
uint8_t *const dst = &pd->dst.buf[(ir * pd->dst.stride + ic) << 2];
|
||||
int ref;
|
||||
const int is_compound = has_second_ref(&mi->mbmi);
|
||||
const INTERP_FILTER interp_filter = mi->mbmi.interp_filter;
|
||||
|
||||
for (ref = 0; ref < 1 + is_compound; ++ref) {
|
||||
const uint8_t *pre =
|
||||
|
@ -676,7 +682,8 @@ void vp10_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane,
|
|||
dst, pd->dst.stride,
|
||||
&mi->bmi[i].as_mv[ref].as_mv,
|
||||
&xd->block_refs[ref]->sf, width, height,
|
||||
ref, interp_filter, MV_PRECISION_Q3,
|
||||
ref, mi->mbmi.interp_filter,
|
||||
MV_PRECISION_Q3,
|
||||
mi_col * MI_SIZE + 4 * ic,
|
||||
mi_row * MI_SIZE + 4 * ir, xd->bd);
|
||||
} else {
|
||||
|
@ -684,7 +691,7 @@ void vp10_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane,
|
|||
dst, pd->dst.stride,
|
||||
&mi->bmi[i].as_mv[ref].as_mv,
|
||||
&xd->block_refs[ref]->sf, width, height, ref,
|
||||
interp_filter, MV_PRECISION_Q3,
|
||||
mi->mbmi.interp_filter, MV_PRECISION_Q3,
|
||||
mi_col * MI_SIZE + 4 * ic,
|
||||
mi_row * MI_SIZE + 4 * ir);
|
||||
}
|
||||
|
@ -693,7 +700,7 @@ void vp10_build_inter_predictor_sub8x8(MACROBLOCKD *xd, int plane,
|
|||
dst, pd->dst.stride,
|
||||
&mi->bmi[i].as_mv[ref].as_mv,
|
||||
&xd->block_refs[ref]->sf, width, height, ref,
|
||||
interp_filter, MV_PRECISION_Q3,
|
||||
mi->mbmi.interp_filter, MV_PRECISION_Q3,
|
||||
mi_col * MI_SIZE + 4 * ic,
|
||||
mi_row * MI_SIZE + 4 * ir);
|
||||
#endif // CONFIG_VP9_HIGHBITDEPTH
|
||||
|
@ -2151,7 +2158,6 @@ static void build_inter_predictors_single_buf(MACROBLOCKD *xd, int plane,
|
|||
int ext_dst_stride) {
|
||||
struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
const MODE_INFO *mi = xd->mi[0];
|
||||
const INTERP_FILTER interp_filter = mi->mbmi.interp_filter;
|
||||
|
||||
const struct scale_factors *const sf = &xd->block_refs[ref]->sf;
|
||||
struct buf_2d *const pre_buf = &pd->pre[ref];
|
||||
|
@ -2199,7 +2205,7 @@ static void build_inter_predictors_single_buf(MACROBLOCKD *xd, int plane,
|
|||
|
||||
vp10_make_inter_predictor(pre, pre_buf->stride, dst, ext_dst_stride,
|
||||
subpel_x, subpel_y, sf, w, h, 0,
|
||||
interp_filter, xs, ys, xd);
|
||||
mi->mbmi.interp_filter, xs, ys, xd);
|
||||
}
|
||||
|
||||
void vp10_build_inter_predictors_for_planes_single_buf(
|
||||
|
|
|
@ -25,16 +25,37 @@ static INLINE void inter_predictor(const uint8_t *src, int src_stride,
|
|||
const int subpel_x,
|
||||
const int subpel_y,
|
||||
const struct scale_factors *sf,
|
||||
int w, int h, int ref,
|
||||
int w, int h, int ref_idx,
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const INTERP_FILTER *interp_filter,
|
||||
#else
|
||||
const INTERP_FILTER interp_filter,
|
||||
#endif
|
||||
int xs, int ys) {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
InterpFilterParams interp_filter_params_x =
|
||||
vp10_get_interp_filter_params(interp_filter[1 + 2 * ref_idx]);
|
||||
InterpFilterParams interp_filter_params_y =
|
||||
vp10_get_interp_filter_params(interp_filter[0 + 2 * ref_idx]);
|
||||
#else
|
||||
InterpFilterParams interp_filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter);
|
||||
#endif
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
if (interp_filter_params_x.taps == SUBPEL_TAPS &&
|
||||
interp_filter_params_y.taps == SUBPEL_TAPS) {
|
||||
const int16_t *kernel_x =
|
||||
vp10_get_interp_filter_subpel_kernel(interp_filter_params_x, subpel_x);
|
||||
const int16_t *kernel_y =
|
||||
vp10_get_interp_filter_subpel_kernel(interp_filter_params_y, subpel_y);
|
||||
#else
|
||||
if (interp_filter_params.taps == SUBPEL_TAPS) {
|
||||
const int16_t *kernel_x =
|
||||
vp10_get_interp_filter_subpel_kernel(interp_filter_params, subpel_x);
|
||||
const int16_t *kernel_y =
|
||||
vp10_get_interp_filter_subpel_kernel(interp_filter_params, subpel_y);
|
||||
#endif
|
||||
#if CONFIG_EXT_INTERP && SUPPORT_NONINTERPOLATING_FILTERS
|
||||
if (IsInterpolatingFilter(interp_filter)) {
|
||||
// Interpolating filter
|
||||
|
@ -47,17 +68,16 @@ static INLINE void inter_predictor(const uint8_t *src, int src_stride,
|
|||
kernel_x, xs, kernel_y, ys, w, h);
|
||||
}
|
||||
#else
|
||||
sf->predict[subpel_x != 0][subpel_y != 0][ref](
|
||||
sf->predict[subpel_x != 0][subpel_y != 0][ref_idx](
|
||||
src, src_stride, dst, dst_stride,
|
||||
kernel_x, xs, kernel_y, ys, w, h);
|
||||
#endif // CONFIG_EXT_INTERP && SUPPORT_NONINTERPOLATING_FILTERS
|
||||
} else {
|
||||
// ref > 0 means this is the second reference frame
|
||||
// ref_idx > 0 means this is the second reference frame
|
||||
// first reference frame's prediction result is already in dst
|
||||
// therefore we need to average the first and second results
|
||||
int avg = ref > 0;
|
||||
vp10_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter_params,
|
||||
subpel_x, xs, subpel_y, ys, avg);
|
||||
vp10_convolve(src, src_stride, dst, dst_stride, w, h, interp_filter,
|
||||
subpel_x, xs, subpel_y, ys, ref_idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,7 +146,11 @@ static INLINE void vp10_make_inter_predictor(
|
|||
const int subpel_y,
|
||||
const struct scale_factors *sf,
|
||||
int w, int h, int ref,
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const INTERP_FILTER *interp_filter,
|
||||
#else
|
||||
const INTERP_FILTER interp_filter,
|
||||
#endif
|
||||
int xs, int ys,
|
||||
const MACROBLOCKD *xd) {
|
||||
(void) xd;
|
||||
|
@ -152,7 +176,11 @@ void vp10_make_masked_inter_predictor(
|
|||
const int subpel_y,
|
||||
const struct scale_factors *sf,
|
||||
int w, int h,
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const INTERP_FILTER *interp_filter,
|
||||
#else
|
||||
const INTERP_FILTER interp_filter,
|
||||
#endif
|
||||
int xs, int ys,
|
||||
#if CONFIG_SUPERTX
|
||||
int wedge_offset_x, int wedge_offset_y,
|
||||
|
@ -284,7 +312,11 @@ void vp10_build_inter_predictor(const uint8_t *src, int src_stride,
|
|||
const MV *mv_q3,
|
||||
const struct scale_factors *sf,
|
||||
int w, int h, int do_avg,
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const INTERP_FILTER *interp_filter,
|
||||
#else
|
||||
const INTERP_FILTER interp_filter,
|
||||
#endif
|
||||
enum mv_precision precision,
|
||||
int x, int y);
|
||||
|
||||
|
@ -325,6 +357,54 @@ void vp10_setup_pre_planes(MACROBLOCKD *xd, int idx,
|
|||
const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
|
||||
const struct scale_factors *sf);
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
// Detect if the block have sub-pixel level motion vectors
|
||||
// per component.
|
||||
static INLINE int has_subpel_mv_component(const MACROBLOCKD *const xd,
|
||||
int dir) {
|
||||
MODE_INFO *const mi = xd->mi[0];
|
||||
MB_MODE_INFO *const mbmi = &mi->mbmi;
|
||||
const BLOCK_SIZE bsize = mbmi->sb_type;
|
||||
int plane;
|
||||
int ref = (dir >> 1);
|
||||
|
||||
if (bsize >= BLOCK_8X8) {
|
||||
if (dir & 0x01) {
|
||||
if (mbmi->mv[ref].as_mv.col & SUBPEL_MASK)
|
||||
return 1;
|
||||
} else {
|
||||
if (mbmi->mv[ref].as_mv.row & SUBPEL_MASK)
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
|
||||
const PARTITION_TYPE bp = BLOCK_8X8 - bsize;
|
||||
const struct macroblockd_plane *const pd = &xd->plane[plane];
|
||||
const int have_vsplit = bp != PARTITION_HORZ;
|
||||
const int have_hsplit = bp != PARTITION_VERT;
|
||||
const int num_4x4_w = 2 >> ((!have_vsplit) | pd->subsampling_x);
|
||||
const int num_4x4_h = 2 >> ((!have_hsplit) | pd->subsampling_y);
|
||||
|
||||
int x, y;
|
||||
for (y = 0; y < num_4x4_h; ++y) {
|
||||
for (x = 0; x < num_4x4_w; ++x) {
|
||||
const MV mv = average_split_mvs(pd, mi, ref, y * 2 + x);
|
||||
if (dir & 0x01) {
|
||||
if (mv.col & SUBPEL_MASK)
|
||||
return 1;
|
||||
} else {
|
||||
if (mv.row & SUBPEL_MASK)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_EXT_INTERP
|
||||
static INLINE int vp10_is_interp_needed(const MACROBLOCKD *const xd) {
|
||||
MODE_INFO *const mi = xd->mi[0];
|
||||
|
|
|
@ -95,10 +95,13 @@ static void convolve_copy(const uint8_t *src, int src_stride, uint8_t *dst,
|
|||
|
||||
void vp10_convolve(const uint8_t *src, int src_stride, uint8_t *dst,
|
||||
int dst_stride, int w, int h,
|
||||
const InterpFilterParams filter_params,
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const INTERP_FILTER *interp_filter,
|
||||
#else
|
||||
const INTERP_FILTER interp_filter,
|
||||
#endif
|
||||
const int subpel_x_q4, int x_step_q4, const int subpel_y_q4,
|
||||
int y_step_q4, int avg) {
|
||||
int filter_size = filter_params.taps;
|
||||
int y_step_q4, int ref_idx) {
|
||||
int ignore_horiz = x_step_q4 == 16 && subpel_x_q4 == 0;
|
||||
int ignore_vert = y_step_q4 == 16 && subpel_y_q4 == 0;
|
||||
|
||||
|
@ -106,16 +109,31 @@ void vp10_convolve(const uint8_t *src, int src_stride, uint8_t *dst,
|
|||
assert(h <= MAX_BLOCK_HEIGHT);
|
||||
assert(y_step_q4 <= MAX_STEP);
|
||||
assert(x_step_q4 <= MAX_STEP);
|
||||
assert(filter_params.taps <= MAX_FILTER_TAP);
|
||||
|
||||
if (ignore_horiz && ignore_vert) {
|
||||
convolve_copy(src, src_stride, dst, dst_stride, w, h, avg);
|
||||
convolve_copy(src, src_stride, dst, dst_stride, w, h, ref_idx);
|
||||
} else if (ignore_vert) {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter[1 + 2 * ref_idx]);
|
||||
#else
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter);
|
||||
#endif
|
||||
assert(filter_params.taps <= MAX_FILTER_TAP);
|
||||
convolve_horiz(src, src_stride, dst, dst_stride, w, h, filter_params,
|
||||
subpel_x_q4, x_step_q4, avg);
|
||||
subpel_x_q4, x_step_q4, ref_idx);
|
||||
} else if (ignore_horiz) {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter[2 * ref_idx]);
|
||||
#else
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter);
|
||||
#endif
|
||||
assert(filter_params.taps <= MAX_FILTER_TAP);
|
||||
convolve_vert(src, src_stride, dst, dst_stride, w, h, filter_params,
|
||||
subpel_y_q4, y_step_q4, avg);
|
||||
subpel_y_q4, y_step_q4, ref_idx);
|
||||
} else {
|
||||
// temp's size is set to (maximum possible intermediate_height) *
|
||||
// MAX_BLOCK_WIDTH
|
||||
|
@ -123,15 +141,34 @@ void vp10_convolve(const uint8_t *src, int src_stride, uint8_t *dst,
|
|||
MAX_FILTER_TAP) *
|
||||
MAX_BLOCK_WIDTH];
|
||||
int temp_stride = MAX_BLOCK_WIDTH;
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter[1 + 2 * ref_idx]);
|
||||
#else
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter);
|
||||
#endif
|
||||
int filter_size = filter_params.taps;
|
||||
int intermediate_height =
|
||||
(((h - 1) * y_step_q4 + subpel_y_q4) >> SUBPEL_BITS) + filter_size;
|
||||
|
||||
assert(filter_params.taps <= MAX_FILTER_TAP);
|
||||
|
||||
convolve_horiz(src - src_stride * (filter_size / 2 - 1), src_stride, temp,
|
||||
temp_stride, w, intermediate_height, filter_params,
|
||||
subpel_x_q4, x_step_q4, 0);
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
filter_params = vp10_get_interp_filter_params(interp_filter[2 * ref_idx]);
|
||||
#else
|
||||
filter_params = vp10_get_interp_filter_params(interp_filter);
|
||||
#endif
|
||||
filter_size = filter_params.taps;
|
||||
assert(filter_params.taps <= MAX_FILTER_TAP);
|
||||
|
||||
convolve_vert(temp + temp_stride * (filter_size / 2 - 1), temp_stride, dst,
|
||||
dst_stride, w, h, filter_params, subpel_y_q4, y_step_q4, avg);
|
||||
dst_stride, w, h, filter_params,
|
||||
subpel_y_q4, y_step_q4, ref_idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,11 @@ extern "C" {
|
|||
void vp10_convolve(const uint8_t *src, int src_stride,
|
||||
uint8_t *dst, int dst_stride,
|
||||
int w, int h,
|
||||
const InterpFilterParams filter_params,
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const INTERP_FILTER *interp_filter,
|
||||
#else
|
||||
const INTERP_FILTER interp_filter,
|
||||
#endif
|
||||
const int subpel_x,
|
||||
const int subpel_y,
|
||||
int xstep, int ystep, int avg);
|
||||
|
|
|
@ -521,7 +521,11 @@ static void extend_and_predict(const uint8_t *buf_ptr1, int pre_buf_stride,
|
|||
int border_offset,
|
||||
uint8_t *const dst, int dst_buf_stride,
|
||||
int subpel_x, int subpel_y,
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const INTERP_FILTER *interp_filter,
|
||||
#else
|
||||
const INTERP_FILTER interp_filter,
|
||||
#endif
|
||||
const struct scale_factors *sf,
|
||||
#if CONFIG_EXT_INTER
|
||||
int wedge_offset_x, int wedge_offset_y,
|
||||
|
@ -563,7 +567,11 @@ static void dec_build_inter_predictors(VP10Decoder *const pbi,
|
|||
int wedge_offset_x, int wedge_offset_y,
|
||||
#endif // CONFIG_EXT_INTER
|
||||
int mi_x, int mi_y,
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const INTERP_FILTER *interp_filter,
|
||||
#else
|
||||
const INTERP_FILTER interp_filter,
|
||||
#endif
|
||||
const struct scale_factors *sf,
|
||||
struct buf_2d *pre_buf,
|
||||
struct buf_2d *dst_buf, const MV* mv,
|
||||
|
@ -670,9 +678,17 @@ static void dec_build_inter_predictors(VP10Decoder *const pbi,
|
|||
int x1 = ((x0_16 + (w - 1) * xs) >> SUBPEL_BITS) + 1;
|
||||
int x_pad = 0, y_pad = 0;
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
InterpFilterParams filter_params_y =
|
||||
vp10_get_interp_filter_params(interp_filter[0]);
|
||||
InterpFilterParams filter_params_x =
|
||||
vp10_get_interp_filter_params(interp_filter[1]);
|
||||
int filter_size = VPXMAX(filter_params_y.taps, filter_params_x.taps);
|
||||
#else
|
||||
InterpFilterParams filter_params =
|
||||
vp10_get_interp_filter_params(interp_filter);
|
||||
int filter_size = filter_params.taps;
|
||||
#endif
|
||||
|
||||
if (subpel_x ||
|
||||
#if CONFIG_EXT_INTERP
|
||||
|
@ -772,7 +788,6 @@ static void dec_build_inter_predictors_sb_extend(
|
|||
const int wedge_offset_y = (mi_row_ori - mi_row) * MI_SIZE;
|
||||
#endif // CONFIG_EXT_INTER
|
||||
const MODE_INFO *mi = xd->mi[0];
|
||||
const INTERP_FILTER interp_filter = mi->mbmi.interp_filter;
|
||||
const BLOCK_SIZE sb_type = mi->mbmi.sb_type;
|
||||
const int is_compound = has_second_ref(&mi->mbmi);
|
||||
|
||||
|
@ -819,7 +834,7 @@ static void dec_build_inter_predictors_sb_extend(
|
|||
wedge_offset_y,
|
||||
#endif // CONFIG_EXT_INTER
|
||||
mi_x, mi_y,
|
||||
interp_filter, sf, pre_buf, dst_buf,
|
||||
mi->mbmi.interp_filter, sf, pre_buf, dst_buf,
|
||||
&mv, ref_frame_buf, is_scaled, ref);
|
||||
}
|
||||
}
|
||||
|
@ -837,7 +852,7 @@ static void dec_build_inter_predictors_sb_extend(
|
|||
wedge_offset_y,
|
||||
#endif // CONFIG_EXT_INTER
|
||||
mi_x, mi_y,
|
||||
interp_filter, sf, pre_buf, dst_buf,
|
||||
mi->mbmi.interp_filter, sf, pre_buf, dst_buf,
|
||||
&mv, ref_frame_buf,
|
||||
is_scaled, ref);
|
||||
}
|
||||
|
@ -874,7 +889,6 @@ static void dec_build_inter_predictors_sb_sub8x8_extend(
|
|||
const int wedge_offset_y = (mi_row_ori - mi_row) * MI_SIZE;
|
||||
#endif // CONFIG_EXT_INTER
|
||||
const MODE_INFO *mi = xd->mi[0];
|
||||
const INTERP_FILTER interp_filter = mi->mbmi.interp_filter;
|
||||
const int is_compound = has_second_ref(&mi->mbmi);
|
||||
|
||||
// For sub8x8 uv:
|
||||
|
@ -910,7 +924,7 @@ static void dec_build_inter_predictors_sb_sub8x8_extend(
|
|||
wedge_offset_y,
|
||||
#endif // CONFIG_EXT_INTER
|
||||
mi_x, mi_y,
|
||||
interp_filter, sf, pre_buf, dst_buf,
|
||||
mi->mbmi.interp_filter, sf, pre_buf, dst_buf,
|
||||
&mv, ref_frame_buf, is_scaled, ref);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -866,6 +866,9 @@ static int read_is_obmc_block(VP10_COMMON *const cm, MACROBLOCKD *const xd,
|
|||
|
||||
static INLINE INTERP_FILTER read_interp_filter(
|
||||
VP10_COMMON *const cm, MACROBLOCKD *const xd,
|
||||
#if CONFIG_DUAL_FILTER
|
||||
int dir,
|
||||
#endif
|
||||
vp10_reader *r) {
|
||||
#if CONFIG_EXT_INTERP
|
||||
if (!vp10_is_interp_needed(xd)) return EIGHTTAP_REGULAR;
|
||||
|
@ -873,7 +876,11 @@ static INLINE INTERP_FILTER read_interp_filter(
|
|||
if (cm->interp_filter != SWITCHABLE) {
|
||||
return cm->interp_filter;
|
||||
} else {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const int ctx = vp10_get_pred_context_switchable_interp(xd, dir);
|
||||
#else
|
||||
const int ctx = vp10_get_pred_context_switchable_interp(xd);
|
||||
#endif
|
||||
FRAME_COUNTS *counts = xd->counts;
|
||||
const INTERP_FILTER type =
|
||||
(INTERP_FILTER)vp10_read_tree(r, vp10_switchable_interp_tree,
|
||||
|
@ -1384,9 +1391,9 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !CONFIG_EXT_INTERP
|
||||
#if !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER
|
||||
mbmi->interp_filter = read_interp_filter(cm, xd, r);
|
||||
#endif // !CONFIG_EXT_INTERP
|
||||
#endif // !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER
|
||||
|
||||
if (bsize < BLOCK_8X8) {
|
||||
const int num_4x4_w = 1 << xd->bmode_blocks_wl;
|
||||
|
@ -1606,9 +1613,21 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
|
|||
}
|
||||
#endif // CONFIG_EXT_INTER
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
for (ref = 0; ref < 4; ++ref) {
|
||||
const int frame_idx = (ref >> 1);
|
||||
mbmi->interp_filter[ref] = (cm->interp_filter == SWITCHABLE) ?
|
||||
EIGHTTAP_REGULAR : cm->interp_filter;
|
||||
|
||||
if (mbmi->ref_frame[frame_idx] > INTRA_FRAME &&
|
||||
has_subpel_mv_component(xd, ref))
|
||||
mbmi->interp_filter[ref] = read_interp_filter(cm, xd, ref, r);
|
||||
}
|
||||
#else
|
||||
#if CONFIG_EXT_INTERP
|
||||
mbmi->interp_filter = read_interp_filter(cm, xd, r);
|
||||
#endif // CONFIG_EXT_INTERP
|
||||
#endif // CONFIG_DUAL_FILTER
|
||||
}
|
||||
|
||||
static void read_inter_frame_mode_info(VP10Decoder *const pbi,
|
||||
|
|
|
@ -920,18 +920,42 @@ static void write_switchable_interp_filter(VP10_COMP *cpi,
|
|||
vp10_writer *w) {
|
||||
VP10_COMMON *const cm = &cpi->common;
|
||||
const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
|
||||
#if CONFIG_DUAL_FILTER
|
||||
int dir;
|
||||
#endif
|
||||
if (cm->interp_filter == SWITCHABLE) {
|
||||
const int ctx = vp10_get_pred_context_switchable_interp(xd);
|
||||
#if CONFIG_EXT_INTERP
|
||||
#if CONFIG_DUAL_FILTER
|
||||
if (!vp10_is_interp_needed(xd)) {
|
||||
assert(mbmi->interp_filter[0] == EIGHTTAP_REGULAR);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (!vp10_is_interp_needed(xd)) {
|
||||
assert(mbmi->interp_filter == EIGHTTAP_REGULAR);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif // CONFIG_DUAL_FILTER
|
||||
#endif // CONFIG_EXT_INTERP
|
||||
#if CONFIG_DUAL_FILTER
|
||||
for (dir = 0; dir < 4; ++dir) {
|
||||
const int frame_idx = (dir >> 1);
|
||||
if (mbmi->ref_frame[frame_idx] > INTRA_FRAME &&
|
||||
has_subpel_mv_component(xd, dir)) {
|
||||
const int ctx = vp10_get_pred_context_switchable_interp(xd, dir);
|
||||
vp10_write_token(w, vp10_switchable_interp_tree,
|
||||
cm->fc->switchable_interp_prob[ctx],
|
||||
&switchable_interp_encodings[mbmi->interp_filter[dir]]);
|
||||
++cpi->interp_filter_selected[0][mbmi->interp_filter[dir]];
|
||||
}
|
||||
}
|
||||
#else
|
||||
const int ctx = vp10_get_pred_context_switchable_interp(xd);
|
||||
vp10_write_token(w, vp10_switchable_interp_tree,
|
||||
cm->fc->switchable_interp_prob[ctx],
|
||||
&switchable_interp_encodings[mbmi->interp_filter]);
|
||||
++cpi->interp_filter_selected[0][mbmi->interp_filter];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1140,7 +1164,7 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
|
|||
}
|
||||
}
|
||||
|
||||
#if !CONFIG_EXT_INTERP
|
||||
#if !CONFIG_EXT_INTERP && !CONFIG_DUAL_FILTER
|
||||
write_switchable_interp_filter(cpi, xd, w);
|
||||
#endif // !CONFIG_EXT_INTERP
|
||||
|
||||
|
@ -1348,7 +1372,7 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
|
|||
}
|
||||
#endif // CONFIG_EXT_INTER
|
||||
|
||||
#if CONFIG_EXT_INTERP
|
||||
#if CONFIG_EXT_INTERP || CONFIG_DUAL_FILTER
|
||||
write_switchable_interp_filter(cpi, xd, w);
|
||||
#endif // CONFIG_EXT_INTERP
|
||||
}
|
||||
|
|
|
@ -927,7 +927,12 @@ static void choose_partitioning(VP10_COMP *const cpi,
|
|||
mbmi->ref_frame[1] = NONE;
|
||||
mbmi->sb_type = cm->sb_size;
|
||||
mbmi->mv[0].as_int = 0;
|
||||
#if CONFIG_DUAL_FILTER
|
||||
for (i = 0; i < 4; ++i)
|
||||
mbmi->interp_filter[i] = BILINEAR;
|
||||
#else
|
||||
mbmi->interp_filter = BILINEAR;
|
||||
#endif
|
||||
|
||||
y_sad = vp10_int_pro_motion_estimation(cpi, x, bsize, mi_row, mi_col);
|
||||
|
||||
|
@ -1018,6 +1023,34 @@ static void choose_partitioning(VP10_COMP *const cpi,
|
|||
set_vt_partitioning(cpi, x, xd, vt, mi_row, mi_col, thre, bmin);
|
||||
}
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
static void reset_intmv_filter_type(VP10_COMMON *cm,
|
||||
MACROBLOCKD *xd, MB_MODE_INFO *mbmi) {
|
||||
int dir;
|
||||
for (dir = 0; dir < 4; ++dir) {
|
||||
const int frame_idx = (dir >> 1);
|
||||
if (mbmi->ref_frame[frame_idx] > INTRA_FRAME &&
|
||||
!has_subpel_mv_component(xd, dir))
|
||||
mbmi->interp_filter[dir] = (cm->interp_filter == SWITCHABLE) ?
|
||||
EIGHTTAP_REGULAR : cm->interp_filter;
|
||||
}
|
||||
}
|
||||
|
||||
static void update_filter_type_count(FRAME_COUNTS *counts,
|
||||
const MACROBLOCKD *xd,
|
||||
const MB_MODE_INFO *mbmi) {
|
||||
int dir;
|
||||
for (dir = 0; dir < 4; ++dir) {
|
||||
const int frame_idx = (dir >> 1);
|
||||
if (mbmi->ref_frame[frame_idx] > INTRA_FRAME &&
|
||||
has_subpel_mv_component(xd, dir)) {
|
||||
const int ctx = vp10_get_pred_context_switchable_interp(xd, dir);
|
||||
++counts->switchable_interp[ctx][mbmi->interp_filter[dir]];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void update_state(VP10_COMP *cpi, ThreadData *td,
|
||||
PICK_MODE_CONTEXT *ctx,
|
||||
int mi_row, int mi_col, BLOCK_SIZE bsize,
|
||||
|
@ -1057,6 +1090,10 @@ static void update_state(VP10_COMP *cpi, ThreadData *td,
|
|||
*mi_addr = *mi;
|
||||
*x->mbmi_ext = ctx->mbmi_ext;
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
reset_intmv_filter_type(cm, xd, mbmi);
|
||||
#endif
|
||||
|
||||
#if CONFIG_REF_MV
|
||||
rf_type = vp10_ref_frame_type(mbmi->ref_frame);
|
||||
if (x->mbmi_ext->ref_mv_count[rf_type] > 1 &&
|
||||
|
@ -1167,8 +1204,12 @@ static void update_state(VP10_COMP *cpi, ThreadData *td,
|
|||
&& vp10_is_interp_needed(xd)
|
||||
#endif
|
||||
) {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
update_filter_type_count(td->counts, xd, mbmi);
|
||||
#else
|
||||
const int ctx = vp10_get_pred_context_switchable_interp(xd);
|
||||
++td->counts->switchable_interp[ctx][mbmi->interp_filter];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1224,6 +1265,10 @@ static void update_state_supertx(VP10_COMP *cpi, ThreadData *td,
|
|||
assert(is_inter_block(mbmi));
|
||||
assert(mbmi->tx_size == ctx->mic.mbmi.tx_size);
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
reset_intmv_filter_type(cm, xd, mbmi);
|
||||
#endif
|
||||
|
||||
#if CONFIG_REF_MV
|
||||
rf_type = vp10_ref_frame_type(mbmi->ref_frame);
|
||||
if (x->mbmi_ext->ref_mv_count[rf_type] > 1 &&
|
||||
|
@ -1311,8 +1356,12 @@ static void update_state_supertx(VP10_COMP *cpi, ThreadData *td,
|
|||
&& vp10_is_interp_needed(xd)
|
||||
#endif
|
||||
) {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
update_filter_type_count(td->counts, xd, mbmi);
|
||||
#else
|
||||
const int ctx = vp10_get_pred_context_switchable_interp(xd);
|
||||
++td->counts->switchable_interp[ctx][mbmi->interp_filter];
|
||||
#endif
|
||||
}
|
||||
|
||||
rdc->comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
|
||||
|
@ -3563,9 +3612,15 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td,
|
|||
subsize = get_subsize(bsize, PARTITION_SPLIT);
|
||||
if (bsize == BLOCK_8X8) {
|
||||
i = 4;
|
||||
#if CONFIG_DUAL_FILTER
|
||||
if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
|
||||
pc_tree->leaf_split[0]->pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter[0];
|
||||
#else
|
||||
if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
|
||||
pc_tree->leaf_split[0]->pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter;
|
||||
#endif
|
||||
#if CONFIG_SUPERTX
|
||||
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
|
||||
&sum_rate_nocoef,
|
||||
|
@ -3747,10 +3802,17 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td,
|
|||
subsize = get_subsize(bsize, PARTITION_HORZ);
|
||||
if (cpi->sf.adaptive_motion_search)
|
||||
load_pred_mv(x, ctx);
|
||||
#if CONFIG_DUAL_FILTER
|
||||
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
|
||||
partition_none_allowed)
|
||||
pc_tree->horizontal[0].pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter[0];
|
||||
#else
|
||||
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
|
||||
partition_none_allowed)
|
||||
pc_tree->horizontal[0].pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter;
|
||||
#endif
|
||||
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
|
||||
#if CONFIG_SUPERTX
|
||||
&sum_rate_nocoef,
|
||||
|
@ -3775,10 +3837,18 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td,
|
|||
|
||||
if (cpi->sf.adaptive_motion_search)
|
||||
load_pred_mv(x, ctx);
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
|
||||
partition_none_allowed)
|
||||
pc_tree->horizontal[1].pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter[0];
|
||||
#else
|
||||
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
|
||||
partition_none_allowed)
|
||||
pc_tree->horizontal[1].pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter;
|
||||
#endif
|
||||
#if CONFIG_SUPERTX
|
||||
rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col,
|
||||
&this_rdc, &this_rate_nocoef,
|
||||
|
@ -3878,10 +3948,18 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td,
|
|||
|
||||
if (cpi->sf.adaptive_motion_search)
|
||||
load_pred_mv(x, ctx);
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
|
||||
partition_none_allowed)
|
||||
pc_tree->vertical[0].pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter[0];
|
||||
#else
|
||||
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
|
||||
partition_none_allowed)
|
||||
pc_tree->vertical[0].pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter;
|
||||
#endif
|
||||
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
|
||||
#if CONFIG_SUPERTX
|
||||
&sum_rate_nocoef,
|
||||
|
@ -3905,10 +3983,18 @@ static void rd_pick_partition(VP10_COMP *cpi, ThreadData *td,
|
|||
|
||||
if (cpi->sf.adaptive_motion_search)
|
||||
load_pred_mv(x, ctx);
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
|
||||
partition_none_allowed)
|
||||
pc_tree->vertical[1].pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter[0];
|
||||
#else
|
||||
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
|
||||
partition_none_allowed)
|
||||
pc_tree->vertical[1].pred_interp_filter =
|
||||
ctx->mic.mbmi.interp_filter;
|
||||
#endif
|
||||
#if CONFIG_SUPERTX
|
||||
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
|
||||
&this_rate_nocoef,
|
||||
|
@ -4477,10 +4563,13 @@ static void encode_frame_internal(VP10_COMP *cpi) {
|
|||
cpi->last_frame_distortion = cpi->frame_distortion;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !CONFIG_DUAL_FILTER
|
||||
static INTERP_FILTER get_cm_interp_filter(VP10_COMP *cpi) {
|
||||
(void)cpi;
|
||||
return SWITCHABLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
void vp10_encode_frame(VP10_COMP *cpi) {
|
||||
VP10_COMMON *const cm = &cpi->common;
|
||||
|
@ -4548,9 +4637,11 @@ void vp10_encode_frame(VP10_COMP *cpi) {
|
|||
else
|
||||
cm->reference_mode = REFERENCE_MODE_SELECT;
|
||||
|
||||
#if !CONFIG_DUAL_FILTER
|
||||
if (cm->interp_filter == SWITCHABLE) {
|
||||
cm->interp_filter = get_cm_interp_filter(cpi);
|
||||
}
|
||||
#endif
|
||||
|
||||
encode_frame_internal(cpi);
|
||||
|
||||
|
@ -4879,6 +4970,7 @@ static void encode_superblock(VP10_COMP *cpi, ThreadData *td,
|
|||
} else {
|
||||
int ref;
|
||||
const int is_compound = has_second_ref(mbmi);
|
||||
|
||||
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
|
||||
for (ref = 0; ref < 1 + is_compound; ++ref) {
|
||||
YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
|
||||
|
|
|
@ -722,6 +722,25 @@ YV12_BUFFER_CONFIG *vp10_get_scaled_ref_frame(const VP10_COMP *cpi,
|
|||
&cm->buffer_pool->frame_bufs[scaled_idx].buf : NULL;
|
||||
}
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
int vp10_get_switchable_rate(const VP10_COMP *cpi,
|
||||
const MACROBLOCKD *const xd) {
|
||||
const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
|
||||
int inter_filter_cost = 0;
|
||||
int dir;
|
||||
|
||||
for (dir = 0; dir < 4; ++dir) {
|
||||
const int frame_idx = (dir >> 1);
|
||||
if (mbmi->ref_frame[frame_idx] > INTRA_FRAME &&
|
||||
has_subpel_mv_component(xd, dir)) {
|
||||
const int ctx = vp10_get_pred_context_switchable_interp(xd, dir);
|
||||
inter_filter_cost +=
|
||||
cpi->switchable_interp_costs[ctx][mbmi->interp_filter[dir]];
|
||||
}
|
||||
}
|
||||
return SWITCHABLE_INTERP_RATE_FACTOR * inter_filter_cost;
|
||||
}
|
||||
#else
|
||||
int vp10_get_switchable_rate(const VP10_COMP *cpi,
|
||||
const MACROBLOCKD *const xd) {
|
||||
const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
|
||||
|
@ -732,6 +751,7 @@ int vp10_get_switchable_rate(const VP10_COMP *cpi,
|
|||
return SWITCHABLE_INTERP_RATE_FACTOR *
|
||||
cpi->switchable_interp_costs[ctx][mbmi->interp_filter];
|
||||
}
|
||||
#endif
|
||||
|
||||
void vp10_set_rd_speed_thresholds(VP10_COMP *cpi) {
|
||||
int i;
|
||||
|
|
|
@ -4607,7 +4607,14 @@ static void joint_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
|
|||
mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]};
|
||||
int_mv ref_mv[2];
|
||||
int ite, ref;
|
||||
#if CONFIG_DUAL_FILTER
|
||||
INTERP_FILTER interp_filter[4] = {
|
||||
mbmi->interp_filter[0], mbmi->interp_filter[1],
|
||||
mbmi->interp_filter[2], mbmi->interp_filter[3],
|
||||
};
|
||||
#else
|
||||
const INTERP_FILTER interp_filter = mbmi->interp_filter;
|
||||
#endif
|
||||
struct scale_factors sf;
|
||||
|
||||
// Do joint motion search in compound mode to get more accurate mv.
|
||||
|
@ -4680,6 +4687,14 @@ static void joint_motion_search(VP10_COMP *cpi, MACROBLOCK *x,
|
|||
ref_yv12[0] = xd->plane[0].pre[0];
|
||||
ref_yv12[1] = xd->plane[0].pre[1];
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
// reload the filter types
|
||||
interp_filter[0] = (id == 0) ?
|
||||
mbmi->interp_filter[2] : mbmi->interp_filter[0];
|
||||
interp_filter[1] = (id == 0) ?
|
||||
mbmi->interp_filter[3] : mbmi->interp_filter[1];
|
||||
#endif
|
||||
|
||||
// Get the prediction block from the 'other' reference frame.
|
||||
#if CONFIG_VP9_HIGHBITDEPTH
|
||||
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
|
||||
|
@ -5255,13 +5270,21 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
|
|||
continue;
|
||||
}
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
(void)run_mv_search;
|
||||
#endif
|
||||
|
||||
if (has_second_rf &&
|
||||
#if CONFIG_EXT_INTER
|
||||
this_mode == NEW_NEWMV &&
|
||||
#else
|
||||
this_mode == NEWMV &&
|
||||
#endif // CONFIG_EXT_INTER
|
||||
#if CONFIG_DUAL_FILTER
|
||||
1) {
|
||||
#else
|
||||
(mbmi->interp_filter == EIGHTTAP_REGULAR || run_mv_search)) {
|
||||
#endif
|
||||
// adjust src pointers
|
||||
mi_buf_shift(x, i);
|
||||
if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
|
||||
|
@ -6182,6 +6205,10 @@ static INTERP_FILTER predict_interp_filter(const VP10_COMP *cpi,
|
|||
const int this_mode = mbmi->mode;
|
||||
int refs[2] = { mbmi->ref_frame[0],
|
||||
(mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
|
||||
#if CONFIG_DUAL_FILTER
|
||||
(void)pred_filter_search;
|
||||
return SWITCHABLE;
|
||||
#else
|
||||
if (pred_filter_search) {
|
||||
INTERP_FILTER af = SWITCHABLE, lf = SWITCHABLE;
|
||||
if (xd->up_available)
|
||||
|
@ -6197,6 +6224,7 @@ static INTERP_FILTER predict_interp_filter(const VP10_COMP *cpi,
|
|||
#endif // CONFIG_EXT_INTER
|
||||
best_filter = af;
|
||||
}
|
||||
#endif
|
||||
if (is_comp_pred) {
|
||||
if (cpi->sf.adaptive_mode_search) {
|
||||
#if CONFIG_EXT_INTER
|
||||
|
@ -6672,7 +6700,12 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
|
|||
int tmp_skip_sb = 0;
|
||||
int64_t tmp_skip_sse = INT64_MAX;
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
for (j = 0; j < 4; ++j)
|
||||
mbmi->interp_filter[j] = i;
|
||||
#else
|
||||
mbmi->interp_filter = i;
|
||||
#endif
|
||||
rs = vp10_get_switchable_rate(cpi, xd);
|
||||
rs_rd = RDCOST(x->rdmult, x->rddiv, rs, 0);
|
||||
|
||||
|
@ -6697,7 +6730,13 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
|
|||
is_comp_interintra_pred ||
|
||||
#endif // CONFIG_EXT_INTER
|
||||
(cm->interp_filter != SWITCHABLE &&
|
||||
(cm->interp_filter == mbmi->interp_filter ||
|
||||
(
|
||||
#if CONFIG_DUAL_FILTER
|
||||
cm->interp_filter == mbmi->interp_filter[0]
|
||||
#else
|
||||
cm->interp_filter == mbmi->interp_filter
|
||||
#endif
|
||||
||
|
||||
(i == 0 && intpel_mv && IsInterpolatingFilter(i))))) {
|
||||
restore_dst_buf(xd, orig_dst, orig_dst_stride);
|
||||
} else {
|
||||
|
@ -6730,7 +6769,11 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
|
|||
|
||||
if (newbest) {
|
||||
best_rd = rd;
|
||||
#if CONFIG_DUAL_FILTER
|
||||
best_filter = mbmi->interp_filter[0];
|
||||
#else
|
||||
best_filter = mbmi->interp_filter;
|
||||
#endif
|
||||
if (cm->interp_filter == SWITCHABLE && i &&
|
||||
!(intpel_mv && IsInterpolatingFilter(i)))
|
||||
best_needs_copy = !best_needs_copy;
|
||||
|
@ -6738,7 +6781,11 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
|
|||
|
||||
if ((cm->interp_filter == SWITCHABLE && newbest) ||
|
||||
(cm->interp_filter != SWITCHABLE &&
|
||||
#if CONFIG_DUAL_FILTER
|
||||
cm->interp_filter == mbmi->interp_filter[0])) {
|
||||
#else
|
||||
cm->interp_filter == mbmi->interp_filter)) {
|
||||
#endif
|
||||
pred_exists = 1;
|
||||
tmp_rd = best_rd;
|
||||
|
||||
|
@ -6754,8 +6801,17 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
|
|||
}
|
||||
|
||||
// Set the appropriate filter
|
||||
#if CONFIG_DUAL_FILTER
|
||||
for (i = 0; i < 4; ++i) {
|
||||
const int frame_idx = (i >> 1);
|
||||
if (mbmi->ref_frame[frame_idx] > INTRA_FRAME)
|
||||
mbmi->interp_filter[i] = cm->interp_filter != SWITCHABLE ?
|
||||
cm->interp_filter : best_filter;
|
||||
}
|
||||
#else
|
||||
mbmi->interp_filter = cm->interp_filter != SWITCHABLE ?
|
||||
cm->interp_filter : best_filter;
|
||||
#endif
|
||||
rs = cm->interp_filter == SWITCHABLE ? vp10_get_switchable_rate(cpi, xd) : 0;
|
||||
|
||||
#if CONFIG_EXT_INTER
|
||||
|
@ -7106,7 +7162,12 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
|
|||
|
||||
#if CONFIG_EXT_INTERP
|
||||
if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE) {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
for (i = 0; i < 4; ++i)
|
||||
mbmi->interp_filter[i] = EIGHTTAP_REGULAR;
|
||||
#else
|
||||
mbmi->interp_filter = EIGHTTAP_REGULAR;
|
||||
#endif
|
||||
pred_exists = 0;
|
||||
}
|
||||
#endif // CONFIG_EXT_INTERP
|
||||
|
@ -7136,8 +7197,13 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
|
|||
memcpy(bsse, x->bsse, sizeof(bsse));
|
||||
}
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
if (!is_comp_pred)
|
||||
single_filter[this_mode][refs[0]] = mbmi->interp_filter[0];
|
||||
#else
|
||||
if (!is_comp_pred)
|
||||
single_filter[this_mode][refs[0]] = mbmi->interp_filter;
|
||||
#endif
|
||||
|
||||
if (cpi->sf.adaptive_mode_search)
|
||||
if (is_comp_pred)
|
||||
|
@ -8190,8 +8256,15 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
|
|||
#endif // CONFIG_EXT_INTRA
|
||||
// Evaluate all sub-pel filters irrespective of whether we can use
|
||||
// them for this frame.
|
||||
#if CONFIG_DUAL_FILTER
|
||||
for (i = 0; i < 4; ++i) {
|
||||
mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE ?
|
||||
EIGHTTAP_REGULAR : cm->interp_filter;
|
||||
}
|
||||
#else
|
||||
mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
|
||||
: cm->interp_filter;
|
||||
#endif
|
||||
mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
|
||||
#if CONFIG_OBMC
|
||||
mbmi->obmc = 0;
|
||||
|
@ -9100,9 +9173,26 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
|
|||
}
|
||||
}
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
assert((cm->interp_filter == SWITCHABLE) ||
|
||||
(cm->interp_filter == best_mbmode.interp_filter[0]) ||
|
||||
!is_inter_block(&best_mbmode));
|
||||
assert((cm->interp_filter == SWITCHABLE) ||
|
||||
(cm->interp_filter == best_mbmode.interp_filter[1]) ||
|
||||
!is_inter_block(&best_mbmode));
|
||||
if (best_mbmode.ref_frame[1] > INTRA_FRAME) {
|
||||
assert((cm->interp_filter == SWITCHABLE) ||
|
||||
(cm->interp_filter == best_mbmode.interp_filter[2]) ||
|
||||
!is_inter_block(&best_mbmode));
|
||||
assert((cm->interp_filter == SWITCHABLE) ||
|
||||
(cm->interp_filter == best_mbmode.interp_filter[3]) ||
|
||||
!is_inter_block(&best_mbmode));
|
||||
}
|
||||
#else
|
||||
assert((cm->interp_filter == SWITCHABLE) ||
|
||||
(cm->interp_filter == best_mbmode.interp_filter) ||
|
||||
!is_inter_block(&best_mbmode));
|
||||
#endif
|
||||
|
||||
if (!cpi->rc.is_src_frame_alt_ref)
|
||||
vp10_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
|
||||
|
@ -9214,21 +9304,41 @@ void vp10_rd_pick_inter_mode_sb_seg_skip(VP10_COMP *cpi,
|
|||
int rs;
|
||||
int best_rs = INT_MAX;
|
||||
for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
int k;
|
||||
for (k = 0; k < 4; ++k)
|
||||
mbmi->interp_filter[k] = i;
|
||||
#else
|
||||
mbmi->interp_filter = i;
|
||||
#endif
|
||||
rs = vp10_get_switchable_rate(cpi, xd);
|
||||
if (rs < best_rs) {
|
||||
best_rs = rs;
|
||||
#if CONFIG_DUAL_FILTER
|
||||
best_filter = mbmi->interp_filter[0];
|
||||
#else
|
||||
best_filter = mbmi->interp_filter;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Set the appropriate filter
|
||||
if (cm->interp_filter == SWITCHABLE) {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
for (i = 0; i < 4; ++i)
|
||||
mbmi->interp_filter[i] = best_filter;
|
||||
#else
|
||||
mbmi->interp_filter = best_filter;
|
||||
#endif
|
||||
rate2 += vp10_get_switchable_rate(cpi, xd);
|
||||
} else {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
for (i = 0; i < 4; ++i)
|
||||
mbmi->interp_filter[0] = cm->interp_filter;
|
||||
#else
|
||||
mbmi->interp_filter = cm->interp_filter;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (cm->reference_mode == REFERENCE_MODE_SELECT)
|
||||
|
@ -9249,8 +9359,13 @@ void vp10_rd_pick_inter_mode_sb_seg_skip(VP10_COMP *cpi,
|
|||
return;
|
||||
}
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
assert((cm->interp_filter == SWITCHABLE) ||
|
||||
(cm->interp_filter == mbmi->interp_filter[0]));
|
||||
#else
|
||||
assert((cm->interp_filter == SWITCHABLE) ||
|
||||
(cm->interp_filter == mbmi->interp_filter));
|
||||
#endif
|
||||
|
||||
vp10_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
|
||||
cpi->sf.adaptive_rd_thresh, bsize, THR_ZEROMV);
|
||||
|
@ -9542,8 +9657,14 @@ void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
|
|||
mbmi->ref_frame[1] = second_ref_frame;
|
||||
// Evaluate all sub-pel filters irrespective of whether we can use
|
||||
// them for this frame.
|
||||
#if CONFIG_DUAL_FILTER
|
||||
for (i = 0; i < 4; ++i)
|
||||
mbmi->interp_filter[i] = cm->interp_filter == SWITCHABLE ?
|
||||
EIGHTTAP_REGULAR : cm->interp_filter;
|
||||
#else
|
||||
mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP_REGULAR
|
||||
: cm->interp_filter;
|
||||
#endif
|
||||
x->skip = 0;
|
||||
set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
|
||||
|
||||
|
@ -9638,7 +9759,13 @@ void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
|
|||
int newbest, rs;
|
||||
int64_t rs_rd;
|
||||
MB_MODE_INFO_EXT *mbmi_ext = x->mbmi_ext;
|
||||
#if CONFIG_DUAL_FILTER
|
||||
int dir;
|
||||
for (dir = 0; dir < 4; ++dir)
|
||||
mbmi->interp_filter[dir] = switchable_filter_index;
|
||||
#else
|
||||
mbmi->interp_filter = switchable_filter_index;
|
||||
#endif
|
||||
tmp_rd = rd_pick_best_sub8x8_mode(cpi, x,
|
||||
&mbmi_ext->ref_mvs[ref_frame][0],
|
||||
second_ref, best_yrd, &rate,
|
||||
|
@ -9651,9 +9778,15 @@ void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
|
|||
bsi, switchable_filter_index,
|
||||
mi_row, mi_col);
|
||||
#if CONFIG_EXT_INTERP
|
||||
#if CONFIG_DUAL_FILTER
|
||||
if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
|
||||
mbmi->interp_filter[0] != EIGHTTAP_REGULAR) // invalid config
|
||||
continue;
|
||||
#else
|
||||
if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
|
||||
mbmi->interp_filter != EIGHTTAP_REGULAR) // invalid config
|
||||
continue;
|
||||
#endif
|
||||
#endif // CONFIG_EXT_INTERP
|
||||
if (tmp_rd == INT64_MAX)
|
||||
continue;
|
||||
|
@ -9664,11 +9797,21 @@ void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
|
|||
|
||||
newbest = (tmp_rd < tmp_best_rd);
|
||||
if (newbest) {
|
||||
#if CONFIG_DUAL_FILTER
|
||||
tmp_best_filter = mbmi->interp_filter[0];
|
||||
#else
|
||||
tmp_best_filter = mbmi->interp_filter;
|
||||
#endif
|
||||
tmp_best_rd = tmp_rd;
|
||||
}
|
||||
if ((newbest && cm->interp_filter == SWITCHABLE) ||
|
||||
(mbmi->interp_filter == cm->interp_filter &&
|
||||
(
|
||||
#if CONFIG_DUAL_FILTER
|
||||
mbmi->interp_filter[0] == cm->interp_filter
|
||||
#else
|
||||
mbmi->interp_filter == cm->interp_filter
|
||||
#endif
|
||||
&&
|
||||
cm->interp_filter != SWITCHABLE)) {
|
||||
tmp_best_rdu = tmp_rd;
|
||||
tmp_best_rate = rate;
|
||||
|
@ -9682,17 +9825,6 @@ void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
|
|||
x->zcoeff_blk[TX_4X4][i] = !x->plane[0].eobs[i];
|
||||
}
|
||||
pred_exists = 1;
|
||||
if (switchable_filter_index == 0 &&
|
||||
sf->use_rd_breakout &&
|
||||
best_rd < INT64_MAX) {
|
||||
if (tmp_best_rdu / 2 > best_rd) {
|
||||
// skip searching the other filters if the first is
|
||||
// already substantially larger than the best so far
|
||||
tmp_best_filter = mbmi->interp_filter;
|
||||
tmp_best_rdu = INT64_MAX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // switchable_filter_index loop
|
||||
}
|
||||
|
@ -9701,8 +9833,14 @@ void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
|
|||
if (tmp_best_rdu == INT64_MAX && pred_exists)
|
||||
continue;
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
for (i = 0; i < 4; ++i)
|
||||
mbmi->interp_filter[i] = (cm->interp_filter == SWITCHABLE ?
|
||||
tmp_best_filter : cm->interp_filter);
|
||||
#else
|
||||
mbmi->interp_filter = (cm->interp_filter == SWITCHABLE ?
|
||||
tmp_best_filter : cm->interp_filter);
|
||||
#endif
|
||||
|
||||
if (!pred_exists) {
|
||||
// Handles the special case when a filter that is not in the
|
||||
|
@ -9718,10 +9856,16 @@ void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
|
|||
bsi, 0,
|
||||
mi_row, mi_col);
|
||||
#if CONFIG_EXT_INTERP
|
||||
#if CONFIG_DUAL_FILTER
|
||||
if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
|
||||
mbmi->interp_filter != EIGHTTAP_REGULAR) {
|
||||
mbmi->interp_filter[0] != EIGHTTAP_REGULAR)
|
||||
for (i = 0; i < 4; ++i)
|
||||
mbmi->interp_filter[i] = EIGHTTAP_REGULAR;
|
||||
#else
|
||||
if (!vp10_is_interp_needed(xd) && cm->interp_filter == SWITCHABLE &&
|
||||
mbmi->interp_filter != EIGHTTAP_REGULAR)
|
||||
mbmi->interp_filter = EIGHTTAP_REGULAR;
|
||||
}
|
||||
#endif // CONFIG_DUAL_FILTER
|
||||
#endif // CONFIG_EXT_INTERP
|
||||
if (tmp_rd == INT64_MAX)
|
||||
continue;
|
||||
|
@ -9968,9 +10112,15 @@ void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
|
|||
return;
|
||||
}
|
||||
|
||||
#if CONFIG_DUAL_FILTER
|
||||
assert((cm->interp_filter == SWITCHABLE) ||
|
||||
(cm->interp_filter == best_mbmode.interp_filter[0]) ||
|
||||
!is_inter_block(&best_mbmode));
|
||||
#else
|
||||
assert((cm->interp_filter == SWITCHABLE) ||
|
||||
(cm->interp_filter == best_mbmode.interp_filter) ||
|
||||
!is_inter_block(&best_mbmode));
|
||||
#endif
|
||||
|
||||
vp10_update_rd_thresh_fact(cm, tile_data->thresh_freq_fact,
|
||||
sf->adaptive_rd_thresh, bsize, best_ref_index);
|
||||
|
|
|
@ -49,7 +49,14 @@ static void temporal_filter_predictors_mb_c(MACROBLOCKD *xd,
|
|||
int uv_stride;
|
||||
|
||||
#if USE_TEMPORALFILTER_12TAP
|
||||
#if CONFIG_DUAL_FILTER
|
||||
const INTERP_FILTER interp_filter[4] = {
|
||||
TEMPORALFILTER_12TAP, TEMPORALFILTER_12TAP,
|
||||
TEMPORALFILTER_12TAP, TEMPORALFILTER_12TAP
|
||||
};
|
||||
#else
|
||||
const INTERP_FILTER interp_filter = TEMPORALFILTER_12TAP;
|
||||
#endif
|
||||
(void)xd;
|
||||
#else
|
||||
const INTERP_FILTER interp_filter = xd->mi[0]->mbmi.interp_filter;
|
||||
|
|
Загрузка…
Ссылка в новой задаче