From eef57c1e9925076fad2b8cb50ce70af559b941ca Mon Sep 17 00:00:00 2001 From: Debargha Mukherjee Date: Wed, 27 Jan 2016 08:09:39 -0800 Subject: [PATCH] Fixes ext-interp experiment Fixes integer pel MV usage for the sub8x8 case, which fixes a rare mismatch issue. Also adds some other minor missing code related to filter threshes. Change-Id: I6b07e6cf9b287ba4b5bd6599af4a7412e50b3bdc --- vp10/common/onyxc_int.h | 48 ------------------- vp10/common/reconinter.h | 95 ++++++++++++++++++++++++++++++++++++++ vp10/encoder/bitstream.c | 1 + vp10/encoder/encodeframe.c | 10 +++- vp10/encoder/encoder.c | 4 +- vp10/encoder/rdopt.c | 1 - 6 files changed, 107 insertions(+), 52 deletions(-) diff --git a/vp10/common/onyxc_int.h b/vp10/common/onyxc_int.h index 23a20d439..b6509cb48 100644 --- a/vp10/common/onyxc_int.h +++ b/vp10/common/onyxc_int.h @@ -546,54 +546,6 @@ static INLINE int txfm_partition_context(TXFM_CONTEXT *above_ctx, } #endif -#if CONFIG_EXT_INTERP -static INLINE int vp10_is_interp_needed(const MACROBLOCKD *const xd) { - MODE_INFO *const mi = xd->mi[0]; - MB_MODE_INFO *const mbmi = &mi->mbmi; - const BLOCK_SIZE bsize = mbmi->sb_type; - const int is_compound = has_second_ref(mbmi); - int intpel_mv; - -#if SUPPORT_NONINTERPOLATING_FILTERS - // TODO(debargha): This is is currently only for experimentation - // with non-interpolating filters. Remove later. - // If any of the filters are non-interpolating, then indicate the - // interpolation filter always. - int i; - for (i = 0; i < SWITCHABLE_FILTERS; ++i) { - if (!IsInterpolatingFilter(i)) return 1; - } -#endif - - // For scaled references, interpolation filter is indicated all the time. - if (vp10_is_scaled(&xd->block_refs[0]->sf)) - return 1; - if (is_compound && vp10_is_scaled(&xd->block_refs[1]->sf)) - return 1; - - if (bsize < BLOCK_8X8) { - intpel_mv = - !mv_has_subpel(&mi->bmi[0].as_mv[0].as_mv) && - !mv_has_subpel(&mi->bmi[1].as_mv[0].as_mv) && - !mv_has_subpel(&mi->bmi[2].as_mv[0].as_mv) && - !mv_has_subpel(&mi->bmi[3].as_mv[0].as_mv); - if (is_compound && intpel_mv) { - intpel_mv &= - !mv_has_subpel(&mi->bmi[0].as_mv[1].as_mv) && - !mv_has_subpel(&mi->bmi[1].as_mv[1].as_mv) && - !mv_has_subpel(&mi->bmi[2].as_mv[1].as_mv) && - !mv_has_subpel(&mi->bmi[3].as_mv[1].as_mv); - } - } else { - intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv); - if (is_compound && intpel_mv) { - intpel_mv &= !mv_has_subpel(&mbmi->mv[1].as_mv); - } - } - return !intpel_mv; -} -#endif // CONFIG_EXT_INTERP - #ifdef __cplusplus } // extern "C" #endif diff --git a/vp10/common/reconinter.h b/vp10/common/reconinter.h index bc2df9e23..0575dd260 100644 --- a/vp10/common/reconinter.h +++ b/vp10/common/reconinter.h @@ -232,6 +232,101 @@ void vp10_setup_dst_planes(struct macroblockd_plane planes[MAX_MB_PLANE], 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_EXT_INTERP +static INLINE int vp10_is_interp_needed(const MACROBLOCKD *const xd) { + MODE_INFO *const mi = xd->mi[0]; + MB_MODE_INFO *const mbmi = &mi->mbmi; + const BLOCK_SIZE bsize = mbmi->sb_type; + const int is_compound = has_second_ref(mbmi); + int intpel_mv; + int plane; + +#if SUPPORT_NONINTERPOLATING_FILTERS + // TODO(debargha): This is is currently only for experimentation + // with non-interpolating filters. Remove later. + // If any of the filters are non-interpolating, then indicate the + // interpolation filter always. + int i; + for (i = 0; i < SWITCHABLE_FILTERS; ++i) { + if (!IsInterpolatingFilter(i)) return 1; + } +#endif + + // For scaled references, interpolation filter is indicated all the time. + if (vp10_is_scaled(&xd->block_refs[0]->sf)) + return 1; + if (is_compound && vp10_is_scaled(&xd->block_refs[1]->sf)) + return 1; + + if (bsize == BLOCK_4X4) { + for (plane = 0; plane < 2; ++plane) { + const struct macroblockd_plane *const pd = &xd->plane[plane]; + MV mv0 = average_split_mvs(pd, mi, 0, 0); + MV mv1 = average_split_mvs(pd, mi, 0, 1); + MV mv2 = average_split_mvs(pd, mi, 0, 2); + MV mv3 = average_split_mvs(pd, mi, 0, 3); + intpel_mv = + !mv_has_subpel(&mv0) && + !mv_has_subpel(&mv1) && + !mv_has_subpel(&mv2) && + !mv_has_subpel(&mv3); + if (is_compound && intpel_mv) { + mv0 = average_split_mvs(pd, mi, 1, 0); + mv1 = average_split_mvs(pd, mi, 1, 1); + mv2 = average_split_mvs(pd, mi, 1, 2); + mv3 = average_split_mvs(pd, mi, 1, 3); + intpel_mv = + !mv_has_subpel(&mv0) && + !mv_has_subpel(&mv1) && + !mv_has_subpel(&mv2) && + !mv_has_subpel(&mv3); + } + if (!intpel_mv) break; + } + } else if (bsize == BLOCK_4X8) { + for (plane = 0; plane < 2; ++plane) { + const struct macroblockd_plane *const pd = &xd->plane[plane]; + MV mv0 = average_split_mvs(pd, mi, 0, 0); + MV mv1 = average_split_mvs(pd, mi, 0, 1); + intpel_mv = + !mv_has_subpel(&mv0) && + !mv_has_subpel(&mv1); + if (is_compound && intpel_mv) { + mv0 = average_split_mvs(pd, mi, 1, 0); + mv1 = average_split_mvs(pd, mi, 1, 1); + intpel_mv = + !mv_has_subpel(&mv0) && + !mv_has_subpel(&mv1); + } + if (!intpel_mv) break; + } + } else if (bsize == BLOCK_8X4) { + for (plane = 0; plane < 2; ++plane) { + const struct macroblockd_plane *const pd = &xd->plane[plane]; + MV mv0 = average_split_mvs(pd, mi, 0, 0); + MV mv1 = average_split_mvs(pd, mi, 0, 2); + intpel_mv = + !mv_has_subpel(&mv0) && + !mv_has_subpel(&mv1); + if (is_compound && intpel_mv) { + mv0 = average_split_mvs(pd, mi, 1, 0); + mv1 = average_split_mvs(pd, mi, 1, 2); + intpel_mv = + !mv_has_subpel(&mv0) && + !mv_has_subpel(&mv1); + } + if (!intpel_mv) break; + } + } else { + intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv); + if (is_compound && intpel_mv) { + intpel_mv &= !mv_has_subpel(&mbmi->mv[1].as_mv); + } + } + return !intpel_mv; +} +#endif // CONFIG_EXT_INTERP #ifdef __cplusplus } // extern "C" #endif diff --git a/vp10/encoder/bitstream.c b/vp10/encoder/bitstream.c index 91fb506cf..0c7967cce 100644 --- a/vp10/encoder/bitstream.c +++ b/vp10/encoder/bitstream.c @@ -24,6 +24,7 @@ #include "vp10/common/entropymv.h" #include "vp10/common/mvref_common.h" #include "vp10/common/pred_common.h" +#include "vp10/common/reconinter.h" #include "vp10/common/seg_common.h" #include "vp10/common/tile_common.h" diff --git a/vp10/encoder/encodeframe.c b/vp10/encoder/encodeframe.c index 1df5f740b..950c5d366 100644 --- a/vp10/encoder/encodeframe.c +++ b/vp10/encoder/encodeframe.c @@ -1179,7 +1179,6 @@ static void update_state(VP10_COMP *cpi, ThreadData *td, if (!frame_is_intra_only(cm)) { if (is_inter_block(mbmi)) { vp10_update_mv_count(td); - if (cm->interp_filter == SWITCHABLE #if CONFIG_EXT_INTERP && vp10_is_interp_needed(xd) @@ -3960,6 +3959,15 @@ static void encode_frame_internal(VP10_COMP *cpi) { static INTERP_FILTER get_interp_filter( const int64_t threshes[SWITCHABLE_FILTER_CONTEXTS], int is_alt_ref) { +#if CONFIG_EXT_INTERP + if (!is_alt_ref && + threshes[EIGHTTAP_SMOOTH2] > threshes[EIGHTTAP_SMOOTH] && + threshes[EIGHTTAP_SMOOTH2] > threshes[EIGHTTAP] && + threshes[EIGHTTAP_SMOOTH2] > threshes[EIGHTTAP_SHARP] && + threshes[EIGHTTAP_SMOOTH2] > threshes[SWITCHABLE - 1]) { + return EIGHTTAP_SMOOTH2; + } +#endif // CONFIG_EXT_INTERP if (!is_alt_ref && threshes[EIGHTTAP_SMOOTH] > threshes[EIGHTTAP] && threshes[EIGHTTAP_SMOOTH] > threshes[EIGHTTAP_SHARP] && diff --git a/vp10/encoder/encoder.c b/vp10/encoder/encoder.c index c9f5fe575..8abe49658 100644 --- a/vp10/encoder/encoder.c +++ b/vp10/encoder/encoder.c @@ -3695,10 +3695,10 @@ static int setup_interp_filter_search_mask(VP10_COMP *cpi) { cpi->refresh_alt_ref_frame) return mask; for (ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref) - for (ifilter = EIGHTTAP; ifilter <= EIGHTTAP_SHARP; ++ifilter) + for (ifilter = EIGHTTAP; ifilter < SWITCHABLE_FILTERS; ++ifilter) ref_total[ref] += cpi->interp_filter_selected[ref][ifilter]; - for (ifilter = EIGHTTAP; ifilter <= EIGHTTAP_SHARP; ++ifilter) { + for (ifilter = EIGHTTAP; ifilter < SWITCHABLE_FILTERS; ++ifilter) { if ((ref_total[LAST_FRAME] && cpi->interp_filter_selected[LAST_FRAME][ifilter] == 0) && #if CONFIG_EXT_REFS diff --git a/vp10/encoder/rdopt.c b/vp10/encoder/rdopt.c index 911194921..809153927 100644 --- a/vp10/encoder/rdopt.c +++ b/vp10/encoder/rdopt.c @@ -7232,7 +7232,6 @@ void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi, mbmi->interp_filter = (cm->interp_filter == SWITCHABLE ? tmp_best_filter : cm->interp_filter); - if (!pred_exists) { // Handles the special case when a filter that is not in the // switchable list (bilinear) is indicated at the frame level -- 2.40.0