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