• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 AOM_AV1_COMMON_AV1_LOOPFILTER_H_
13 #define AOM_AV1_COMMON_AV1_LOOPFILTER_H_
14 
15 #include "config/aom_config.h"
16 
17 #include "aom_ports/mem.h"
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 enum lf_path {
31   LF_PATH_420,
32   LF_PATH_444,
33   LF_PATH_SLOW,
34 };
35 
36 typedef struct {
37   uint64_t bits[4];
38 } FilterMask;
39 
40 #if LOOP_FILTER_BITMASK
41 // This structure holds bit masks for all 4x4 blocks in a 64x64 region.
42 // Each 1 bit represents a position in which we want to apply the loop filter.
43 // For Y plane, 4x4 in 64x64 requires 16x16 = 256 bit, therefore we use 4
44 // uint64_t; For U, V plane, for 420 format, plane size is 32x32, thus we use
45 // a uint64_t to represent bitmask.
46 // Left_ entries refer to whether we apply a filter on the border to the
47 // left of the block.   Above_ entries refer to whether or not to apply a
48 // filter on the above border.
49 // Since each transform is accompanied by a potentially different type of
50 // loop filter there is a different entry in the array for each transform size.
51 typedef struct {
52   FilterMask left_y[TX_SIZES];
53   FilterMask above_y[TX_SIZES];
54   FilterMask left_u[TX_SIZES];
55   FilterMask above_u[TX_SIZES];
56   FilterMask left_v[TX_SIZES];
57   FilterMask above_v[TX_SIZES];
58 
59   // Y plane vertical edge and horizontal edge filter level
60   uint8_t lfl_y_hor[MI_SIZE_64X64][MI_SIZE_64X64];
61   uint8_t lfl_y_ver[MI_SIZE_64X64][MI_SIZE_64X64];
62 
63   // U plane filter level
64   uint8_t lfl_u_ver[MI_SIZE_64X64][MI_SIZE_64X64];
65   uint8_t lfl_u_hor[MI_SIZE_64X64][MI_SIZE_64X64];
66 
67   // V plane filter level
68   uint8_t lfl_v_ver[MI_SIZE_64X64][MI_SIZE_64X64];
69   uint8_t lfl_v_hor[MI_SIZE_64X64][MI_SIZE_64X64];
70 
71   // other info
72   FilterMask skip;
73   FilterMask is_vert_border;
74   FilterMask is_horz_border;
75   // Y or UV planes, 5 tx sizes: 4x4, 8x8, 16x16, 32x32, 64x64
76   FilterMask tx_size_ver[2][5];
77   FilterMask tx_size_hor[2][5];
78 } LoopFilterMask;
79 #endif  // LOOP_FILTER_BITMASK
80 
81 struct loopfilter {
82   int filter_level[2];
83   int filter_level_u;
84   int filter_level_v;
85 
86   int sharpness_level;
87 
88   uint8_t mode_ref_delta_enabled;
89   uint8_t mode_ref_delta_update;
90 
91   // 0 = Intra, Last, Last2+Last3,
92   // GF, BRF, ARF2, ARF
93   int8_t ref_deltas[REF_FRAMES];
94 
95   // 0 = ZERO_MV, MV
96   int8_t mode_deltas[MAX_MODE_LF_DELTAS];
97 
98   int combine_vert_horz_lf;
99 
100 #if LOOP_FILTER_BITMASK
101   LoopFilterMask *lfm;
102   size_t lfm_num;
103   int lfm_stride;
104 #endif  // LOOP_FILTER_BITMASK
105 };
106 
107 // Need to align this structure so when it is declared and
108 // passed it can be loaded into vector registers.
109 typedef struct {
110   DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, mblim[SIMD_WIDTH]);
111   DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, lim[SIMD_WIDTH]);
112   DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, hev_thr[SIMD_WIDTH]);
113 } loop_filter_thresh;
114 
115 typedef struct {
116   loop_filter_thresh lfthr[MAX_LOOP_FILTER + 1];
117   uint8_t lvl[MAX_MB_PLANE][MAX_SEGMENTS][2][REF_FRAMES][MAX_MODE_LF_DELTAS];
118 } loop_filter_info_n;
119 
120 /* assorted loopfilter functions which get used elsewhere */
121 struct AV1Common;
122 struct macroblockd;
123 struct AV1LfSyncData;
124 
125 void av1_loop_filter_init(struct AV1Common *cm);
126 
127 void av1_loop_filter_frame_init(struct AV1Common *cm, int plane_start,
128                                 int plane_end);
129 
130 #if LOOP_FILTER_BITMASK
131 void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
132                            struct macroblockd *mbd, int is_decoding,
133                            int plane_start, int plane_end, int partial_frame);
134 #else
135 void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
136                            struct macroblockd *mbd, int plane_start,
137                            int plane_end, int partial_frame);
138 #endif
139 
140 void av1_filter_block_plane_vert(const struct AV1Common *const cm,
141                                  const MACROBLOCKD *const xd, const int plane,
142                                  const MACROBLOCKD_PLANE *const plane_ptr,
143                                  const uint32_t mi_row, const uint32_t mi_col);
144 
145 void av1_filter_block_plane_horz(const struct AV1Common *const cm,
146                                  const MACROBLOCKD *const xd, const int plane,
147                                  const MACROBLOCKD_PLANE *const plane_ptr,
148                                  const uint32_t mi_row, const uint32_t mi_col);
149 
150 typedef struct LoopFilterWorkerData {
151   YV12_BUFFER_CONFIG *frame_buffer;
152   struct AV1Common *cm;
153   struct macroblockd_plane planes[MAX_MB_PLANE];
154   // TODO(Ranjit): When the filter functions are modified to use xd->lossless
155   // add lossless as a member here.
156   MACROBLOCKD *xd;
157 } LFWorkerData;
158 
159 uint8_t get_filter_level(const struct AV1Common *cm,
160                          const loop_filter_info_n *lfi_n, const int dir_idx,
161                          int plane, const MB_MODE_INFO *mbmi);
162 #if LOOP_FILTER_BITMASK
163 void av1_setup_bitmask(struct AV1Common *const cm, int mi_row, int mi_col,
164                        int plane, int subsampling_x, int subsampling_y,
165                        int row_end, int col_end);
166 
167 void av1_filter_block_plane_ver(struct AV1Common *const cm,
168                                 struct macroblockd_plane *const plane_ptr,
169                                 int pl, int mi_row, int mi_col);
170 
171 void av1_filter_block_plane_hor(struct AV1Common *const cm,
172                                 struct macroblockd_plane *const plane, int pl,
173                                 int mi_row, int mi_col);
174 LoopFilterMask *get_loop_filter_mask(const struct AV1Common *const cm,
175                                      int mi_row, int mi_col);
176 int get_index_shift(int mi_col, int mi_row, int *index);
177 
178 void av1_build_bitmask_vert_info(
179     struct AV1Common *const cm, const struct macroblockd_plane *const plane_ptr,
180     int plane);
181 
182 void av1_build_bitmask_horz_info(
183     struct AV1Common *const cm, const struct macroblockd_plane *const plane_ptr,
184     int plane);
185 
186 void av1_filter_block_plane_bitmask_vert(
187     struct AV1Common *const cm, struct macroblockd_plane *const plane_ptr,
188     int pl, int mi_row, int mi_col);
189 
190 void av1_filter_block_plane_bitmask_horz(
191     struct AV1Common *const cm, struct macroblockd_plane *const plane_ptr,
192     int pl, int mi_row, int mi_col);
193 
194 #endif  // LOOP_FILTER_BITMASK
195 
196 extern const int mask_id_table_tx_4x4[BLOCK_SIZES_ALL];
197 
198 extern const int mask_id_table_tx_8x8[BLOCK_SIZES_ALL];
199 
200 extern const int mask_id_table_tx_16x16[BLOCK_SIZES_ALL];
201 
202 extern const int mask_id_table_tx_32x32[BLOCK_SIZES_ALL];
203 
204 // corresponds to entry id in table left_mask_univariant_reordered,
205 // of block size mxn and TX_mxn.
206 extern const int mask_id_table_vert_border[BLOCK_SIZES_ALL];
207 
208 extern const FilterMask left_mask_univariant_reordered[67];
209 
210 extern const FilterMask above_mask_univariant_reordered[67];
211 
212 #ifdef __cplusplus
213 }  // extern "C"
214 #endif
215 
216 #endif  // AOM_AV1_COMMON_AV1_LOOPFILTER_H_
217