1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #ifndef AV1_COMMON_FILTER_H_
13 #define AV1_COMMON_FILTER_H_
14
15 #include <assert.h>
16
17 #include "./aom_config.h"
18 #include "aom/aom_integer.h"
19 #include "aom_dsp/aom_filter.h"
20 #include "aom_ports/mem.h"
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 #define USE_TEMPORALFILTER_12TAP 1
27 #define MAX_FILTER_TAP 12
28
29 #define USE_12TAP_FILTER 0
30 #define USE_EXTRA_FILTER 0
31
32 typedef enum {
33 EIGHTTAP_REGULAR,
34 EIGHTTAP_SMOOTH,
35 #if USE_EXTRA_FILTER
36 EIGHTTAP_SMOOTH2,
37 #endif // USE_EXTRA_FILTER
38 MULTITAP_SHARP,
39 BILINEAR,
40 #if USE_EXTRA_FILTER
41 EIGHTTAP_SHARP,
42 FILTER_REGULAR_UV,
43 FILTER_SMOOTH_UV,
44 FILTER_SHARP_UV,
45 FILTER_SMOOTH2_UV,
46 #endif // USE_EXTRA_FILTER
47 INTERP_FILTERS_ALL,
48 SWITCHABLE_FILTERS = BILINEAR,
49 SWITCHABLE = SWITCHABLE_FILTERS + 1, /* the last switchable one */
50 EXTRA_FILTERS = INTERP_FILTERS_ALL - SWITCHABLE_FILTERS,
51 #if USE_TEMPORALFILTER_12TAP
52 TEMPORALFILTER_12TAP = SWITCHABLE_FILTERS + EXTRA_FILTERS,
53 #endif
54 } InterpFilter;
55
56 // With CONFIG_DUAL_FILTER, pack two InterpFilter's into a uint32_t: since
57 // there are at most 10 filters, we can use 16 bits for each and have more than
58 // enough space. This reduces argument passing and unifies the operation of
59 // setting a (pair of) filters.
60 //
61 // Without CONFIG_DUAL_FILTER,
62 #if CONFIG_DUAL_FILTER
63 typedef uint32_t InterpFilters;
av1_extract_interp_filter(InterpFilters filters,int x_filter)64 static INLINE InterpFilter av1_extract_interp_filter(InterpFilters filters,
65 int x_filter) {
66 return (InterpFilter)((filters >> (x_filter ? 16 : 0)) & 0xffff);
67 }
68
av1_make_interp_filters(InterpFilter y_filter,InterpFilter x_filter)69 static INLINE InterpFilters av1_make_interp_filters(InterpFilter y_filter,
70 InterpFilter x_filter) {
71 uint16_t y16 = y_filter & 0xffff;
72 uint16_t x16 = x_filter & 0xffff;
73 return y16 | ((uint32_t)x16 << 16);
74 }
75
av1_broadcast_interp_filter(InterpFilter filter)76 static INLINE InterpFilters av1_broadcast_interp_filter(InterpFilter filter) {
77 return av1_make_interp_filters(filter, filter);
78 }
79 #else
80 typedef InterpFilter InterpFilters;
av1_extract_interp_filter(InterpFilters filters,int x_filter)81 static INLINE InterpFilter av1_extract_interp_filter(InterpFilters filters,
82 int x_filter) {
83 #ifdef NDEBUG
84 (void)x_filter;
85 #endif
86 assert(!x_filter);
87 return filters;
88 }
89
av1_broadcast_interp_filter(InterpFilter filter)90 static INLINE InterpFilters av1_broadcast_interp_filter(InterpFilter filter) {
91 return filter;
92 }
93 #endif
94
av1_unswitchable_filter(InterpFilter filter)95 static INLINE InterpFilter av1_unswitchable_filter(InterpFilter filter) {
96 return filter == SWITCHABLE ? EIGHTTAP_REGULAR : filter;
97 }
98
99 #if USE_EXTRA_FILTER
100 #define LOG_SWITCHABLE_FILTERS \
101 3 /* (1 << LOG_SWITCHABLE_FILTERS) > SWITCHABLE_FILTERS */
102 #else
103 #define LOG_SWITCHABLE_FILTERS \
104 2 /* (1 << LOG_SWITCHABLE_FILTERS) > SWITCHABLE_FILTERS */
105 #endif
106
107 #if CONFIG_DUAL_FILTER
108 #define MAX_SUBPEL_TAPS 12
109 #define SWITCHABLE_FILTER_CONTEXTS ((SWITCHABLE_FILTERS + 1) * 4)
110 #define INTER_FILTER_COMP_OFFSET (SWITCHABLE_FILTERS + 1)
111 #define INTER_FILTER_DIR_OFFSET ((SWITCHABLE_FILTERS + 1) * 2)
112 #else // CONFIG_DUAL_FILTER
113 #define SWITCHABLE_FILTER_CONTEXTS (SWITCHABLE_FILTERS + 1)
114 #endif // CONFIG_DUAL_FILTER
115
116 #if CONFIG_EXT_INTRA
117 #if CONFIG_INTRA_INTERP
118 typedef enum {
119 INTRA_FILTER_LINEAR,
120 INTRA_FILTER_8TAP,
121 INTRA_FILTER_8TAP_SHARP,
122 INTRA_FILTER_8TAP_SMOOTH,
123 INTRA_FILTERS,
124 } INTRA_FILTER;
125
126 extern const InterpKernel *av1_intra_filter_kernels[INTRA_FILTERS];
127 #endif // CONFIG_INTRA_INTERP
128 #endif // CONFIG_EXT_INTRA
129
130 typedef struct InterpFilterParams {
131 const int16_t *filter_ptr;
132 uint16_t taps;
133 uint16_t subpel_shifts;
134 InterpFilter interp_filter;
135 } InterpFilterParams;
136
137 InterpFilterParams av1_get_interp_filter_params(
138 const InterpFilter interp_filter);
139
140 const int16_t *av1_get_interp_filter_kernel(const InterpFilter interp_filter);
141
av1_get_interp_filter_subpel_kernel(const InterpFilterParams filter_params,const int subpel)142 static INLINE const int16_t *av1_get_interp_filter_subpel_kernel(
143 const InterpFilterParams filter_params, const int subpel) {
144 return filter_params.filter_ptr + filter_params.taps * subpel;
145 }
146
av1_is_interpolating_filter(const InterpFilter interp_filter)147 static INLINE int av1_is_interpolating_filter(
148 const InterpFilter interp_filter) {
149 const InterpFilterParams ip = av1_get_interp_filter_params(interp_filter);
150 return (ip.filter_ptr[ip.taps / 2 - 1] == 128);
151 }
152
153 #if CONFIG_DUAL_FILTER
154 InterpFilter av1_get_plane_interp_filter(InterpFilter interp_filter, int plane);
155 #endif
156
157 #ifdef __cplusplus
158 } // extern "C"
159 #endif
160
161 #endif // AV1_COMMON_FILTER_H_
162