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