]> granicus.if.org Git - libvpx/commitdiff
Fixes ext-interp experiment
authorDebargha Mukherjee <debargha@google.com>
Wed, 27 Jan 2016 16:09:39 +0000 (08:09 -0800)
committerDebargha Mukherjee <debargha@google.com>
Wed, 27 Jan 2016 17:24:48 +0000 (09:24 -0800)
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
vp10/common/reconinter.h
vp10/encoder/bitstream.c
vp10/encoder/encodeframe.c
vp10/encoder/encoder.c
vp10/encoder/rdopt.c

index 23a20d439832d508479464aab3ceb1ee8730a73c..b6509cb484dad9c2d46956c16d0c5ee8999715b2 100644 (file)
@@ -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
index bc2df9e23e09c434f5d3d8d1a42563994e793431..0575dd260773cc19ac42b37177105d378b0bd298 100644 (file)
@@ -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
index 91fb506cf92015f7063591abef734b84210b15bd..0c7967cce7069da1e68296283c22453341d00dee 100644 (file)
@@ -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"
 
index 1df5f740bc91eeff60c6707898fd0c66c5f95a64..950c5d366e57d4d3ab0ee8aa2cd6e057898aa7f2 100644 (file)
@@ -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] &&
index c9f5fe5757d9502cffa1a27936141d9a9a166a23..8abe49658c6ae7b8c3205fd4e8fcb695b67aaa1b 100644 (file)
@@ -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
index 9111949219543e1252f3ec2a5a78dba45917fffa..809153927d4701ea20cbccf996344d71867bac0c 100644 (file)
@@ -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