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_LOOPFILTER_H_
13 #define AV1_COMMON_LOOPFILTER_H_
14 
15 #include "aom_ports/mem.h"
16 #include "./aom_config.h"
17 
18 #include "av1/common/blockd.h"
19 #include "av1/common/seg_common.h"
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 #define MAX_LOOP_FILTER 63
26 #define MAX_SHARPNESS 7
27 
28 #define SIMD_WIDTH 16
29 
30 #define MAX_MODE_LF_DELTAS 2
31 
32 enum lf_path {
33   LF_PATH_420,
34   LF_PATH_444,
35   LF_PATH_SLOW,
36 };
37 
38 struct loopfilter {
39 #if CONFIG_LOOPFILTER_LEVEL
40   int filter_level[2];
41   int filter_level_u;
42   int filter_level_v;
43 #else
44   int filter_level;
45 #endif
46 
47   int sharpness_level;
48   int last_sharpness_level;
49 
50   uint8_t mode_ref_delta_enabled;
51   uint8_t mode_ref_delta_update;
52 
53   // 0 = Intra, Last, Last2+Last3(CONFIG_EXT_REFS),
54   // GF, BRF(CONFIG_EXT_REFS), ARF2(CONFIG_EXT_REFS), ARF
55   int8_t ref_deltas[TOTAL_REFS_PER_FRAME];
56   int8_t last_ref_deltas[TOTAL_REFS_PER_FRAME];
57 
58   // 0 = ZERO_MV, MV
59   int8_t mode_deltas[MAX_MODE_LF_DELTAS];
60   int8_t last_mode_deltas[MAX_MODE_LF_DELTAS];
61 };
62 
63 // Need to align this structure so when it is declared and
64 // passed it can be loaded into vector registers.
65 typedef struct {
66   DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, mblim[SIMD_WIDTH]);
67   DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, lim[SIMD_WIDTH]);
68   DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, hev_thr[SIMD_WIDTH]);
69 } loop_filter_thresh;
70 
71 typedef struct {
72   loop_filter_thresh lfthr[MAX_LOOP_FILTER + 1];
73 #if CONFIG_LOOPFILTER_LEVEL
74   uint8_t lvl[MAX_SEGMENTS][2][TOTAL_REFS_PER_FRAME][MAX_MODE_LF_DELTAS];
75 #else
76   uint8_t lvl[MAX_SEGMENTS][TOTAL_REFS_PER_FRAME][MAX_MODE_LF_DELTAS];
77 #endif
78 } loop_filter_info_n;
79 
80 // This structure holds bit masks for all 8x8 blocks in a 64x64 region.
81 // Each 1 bit represents a position in which we want to apply the loop filter.
82 // Left_ entries refer to whether we apply a filter on the border to the
83 // left of the block.   Above_ entries refer to whether or not to apply a
84 // filter on the above border.   Int_ entries refer to whether or not to
85 // apply borders on the 4x4 edges within the 8x8 block that each bit
86 // represents.
87 // Since each transform is accompanied by a potentially different type of
88 // loop filter there is a different entry in the array for each transform size.
89 typedef struct {
90   uint64_t left_y[TX_SIZES];
91   uint64_t above_y[TX_SIZES];
92   uint64_t int_4x4_y;
93   uint16_t left_uv[TX_SIZES];
94   uint16_t above_uv[TX_SIZES];
95   uint16_t left_int_4x4_uv;
96   uint16_t above_int_4x4_uv;
97   uint8_t lfl_y[MAX_MIB_SIZE][MAX_MIB_SIZE];
98   uint8_t lfl_uv[MAX_MIB_SIZE / 2][MAX_MIB_SIZE / 2];
99 } LOOP_FILTER_MASK;
100 
101 /* assorted loopfilter functions which get used elsewhere */
102 struct AV1Common;
103 struct macroblockd;
104 struct AV1LfSyncData;
105 
106 // This function sets up the bit masks for the entire 64x64 region represented
107 // by mi_row, mi_col.
108 void av1_setup_mask(struct AV1Common *const cm, const int mi_row,
109                     const int mi_col, MODE_INFO **mi_8x8,
110                     const int mode_info_stride, LOOP_FILTER_MASK *lfm);
111 
112 void av1_filter_block_plane_ss00_ver(struct AV1Common *const cm,
113                                      struct macroblockd_plane *const plane,
114                                      int mi_row, LOOP_FILTER_MASK *lfm);
115 void av1_filter_block_plane_ss00_hor(struct AV1Common *const cm,
116                                      struct macroblockd_plane *const plane,
117                                      int mi_row, LOOP_FILTER_MASK *lfm);
118 void av1_filter_block_plane_ss11_ver(struct AV1Common *const cm,
119                                      struct macroblockd_plane *const plane,
120                                      int mi_row, LOOP_FILTER_MASK *lfm);
121 void av1_filter_block_plane_ss11_hor(struct AV1Common *const cm,
122                                      struct macroblockd_plane *const plane,
123                                      int mi_row, LOOP_FILTER_MASK *lfm);
124 
125 void av1_filter_block_plane_non420_ver(struct AV1Common *const cm,
126                                        struct macroblockd_plane *plane,
127                                        MODE_INFO **mi_8x8, int mi_row,
128                                        int mi_col, int pl);
129 void av1_filter_block_plane_non420_hor(struct AV1Common *const cm,
130                                        struct macroblockd_plane *plane,
131                                        MODE_INFO **mi_8x8, int mi_row,
132                                        int mi_col, int pl);
133 
134 void av1_loop_filter_init(struct AV1Common *cm);
135 
136 // Update the loop filter for the current frame.
137 // This should be called before av1_loop_filter_rows(),
138 // av1_loop_filter_frame()
139 // calls this function directly.
140 void av1_loop_filter_frame_init(struct AV1Common *cm, int default_filt_lvl,
141                                 int default_filt_lvl_r
142 #if CONFIG_LOOPFILTER_LEVEL
143                                 ,
144                                 int plane
145 #endif
146                                 );
147 
148 #if CONFIG_LPF_SB
149 void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
150                            struct macroblockd *mbd, int filter_level,
151                            int y_only, int partial_frame, int mi_row,
152                            int mi_col);
153 
154 // Apply the loop filter to [start, stop) macro block rows in frame_buffer.
155 void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer,
156                           struct AV1Common *cm,
157                           struct macroblockd_plane *planes, int start, int stop,
158                           int col_start, int col_end, int y_only);
159 
160 void av1_loop_filter_sb_level_init(struct AV1Common *cm, int mi_row, int mi_col,
161                                    int lvl);
162 #else
163 void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
164                            struct macroblockd *mbd, int filter_level,
165 #if CONFIG_LOOPFILTER_LEVEL
166                            int filter_level_r,
167 #endif
168                            int y_only, int partial_frame);
169 
170 // Apply the loop filter to [start, stop) macro block rows in frame_buffer.
171 void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer,
172                           struct AV1Common *cm,
173                           struct macroblockd_plane *planes, int start, int stop,
174                           int y_only);
175 #endif  // CONFIG_LPF_SB
176 
177 typedef struct LoopFilterWorkerData {
178   YV12_BUFFER_CONFIG *frame_buffer;
179   struct AV1Common *cm;
180   struct macroblockd_plane planes[MAX_MB_PLANE];
181 
182   int start;
183   int stop;
184   int y_only;
185 } LFWorkerData;
186 
187 void av1_loop_filter_data_reset(LFWorkerData *lf_data,
188                                 YV12_BUFFER_CONFIG *frame_buffer,
189                                 struct AV1Common *cm,
190                                 const struct macroblockd_plane *planes);
191 
192 // Operates on the rows described by 'lf_data'.
193 int av1_loop_filter_worker(LFWorkerData *const lf_data, void *unused);
194 #ifdef __cplusplus
195 }  // extern "C"
196 #endif
197 
198 #endif  // AV1_COMMON_LOOPFILTER_H_
199