Pack InterpFilters into a single integer

Before this patch, if CONFIG_DUAL_FILTER was true then an MB_MODE_INFO
stored its filter choices as an array of four numbers, each of which
was between 0 and 10. It also seems that elements 2 and 3 of the array
were always the same as elements 0 and 1 when used.

This patch defines a new type(def) called InterpFilters together with
constructor and extractor functions. When CONFIG_DUAL_FILTER is zero,
InterpFilters is a synonym for InterpFilter and the constructor and
extractor functions should compile away to nothing. When it is
nonzero, InterpFilters is a uint32_t which stores the x filter in the
high part and the y filter in the low part (this looks strange, but
matches the old numbering).

Making this change allows us to get rid of lots of special case code
that was dependent on CONFIG_DUAL_FILTER. The uniform
extract/make/broadcast interface also actually shortens code in
general.

Change-Id: I6b24a61bac3e4b220d8d46d0b27cfe865dcfba81
diff --git a/av1/common/filter.h b/av1/common/filter.h
index e2b1663..01b340f 100644
--- a/av1/common/filter.h
+++ b/av1/common/filter.h
@@ -12,6 +12,8 @@
 #ifndef AV1_COMMON_FILTER_H_
 #define AV1_COMMON_FILTER_H_
 
+#include <assert.h>
+
 #include "./aom_config.h"
 #include "aom/aom_integer.h"
 #include "aom_dsp/aom_filter.h"
@@ -51,6 +53,46 @@
 #endif
 } InterpFilter;
 
+// With CONFIG_DUAL_FILTER, pack two InterpFilter's into a uint32_t: since
+// there are at most 10 filters, we can use 16 bits for each and have more than
+// enough space. This reduces argument passing and unifies the operation of
+// setting a (pair of) filters.
+//
+// Without CONFIG_DUAL_FILTER,
+#if CONFIG_DUAL_FILTER
+typedef uint32_t InterpFilters;
+static INLINE InterpFilter av1_extract_interp_filter(InterpFilters filters,
+                                                     int x_filter) {
+  return (InterpFilter)((filters >> (x_filter ? 16 : 0)) & 0xffff);
+}
+
+static INLINE InterpFilters av1_make_interp_filters(InterpFilter y_filter,
+                                                    InterpFilter x_filter) {
+  uint16_t y16 = y_filter & 0xffff;
+  uint16_t x16 = x_filter & 0xffff;
+  return y16 | ((uint32_t)x16 << 16);
+}
+
+static INLINE InterpFilters av1_broadcast_interp_filter(InterpFilter filter) {
+  return av1_make_interp_filters(filter, filter);
+}
+#else
+typedef InterpFilter InterpFilters;
+static INLINE InterpFilter av1_extract_interp_filter(InterpFilters filters,
+                                                     int x_filter) {
+  assert(!x_filter);
+  return filters;
+}
+
+static INLINE InterpFilters av1_broadcast_interp_filter(InterpFilter filter) {
+  return filter;
+}
+#endif
+
+static INLINE InterpFilter av1_unswitchable_filter(InterpFilter filter) {
+  return filter == SWITCHABLE ? EIGHTTAP_REGULAR : filter;
+}
+
 #if USE_EXTRA_FILTER
 #define LOG_SWITCHABLE_FILTERS \
   3 /* (1 << LOG_SWITCHABLE_FILTERS) > SWITCHABLE_FILTERS */