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/internal/aom_codec_internal.h" 18 19 #include "aom_ports/mem.h" 20 #include "av1/common/blockd.h" 21 #include "av1/common/seg_common.h" 22 23 #ifdef __cplusplus 24 extern "C" { 25 #endif 26 27 #define MAX_LOOP_FILTER 63 28 #define MAX_SHARPNESS 7 29 30 #define SIMD_WIDTH 16 31 32 enum lf_path { 33 LF_PATH_420, 34 LF_PATH_444, 35 LF_PATH_SLOW, 36 }; 37 38 /*!\cond */ 39 enum { VERT_EDGE = 0, HORZ_EDGE = 1, NUM_EDGE_DIRS } UENUM1BYTE(EDGE_DIR); 40 typedef struct { 41 uint64_t bits[4]; 42 } FilterMask; 43 44 struct loopfilter { 45 int filter_level[2]; 46 int filter_level_u; 47 int filter_level_v; 48 49 int sharpness_level; 50 51 uint8_t mode_ref_delta_enabled; 52 uint8_t mode_ref_delta_update; 53 54 // 0 = Intra, Last, Last2+Last3, 55 // GF, BRF, ARF2, ARF 56 int8_t ref_deltas[REF_FRAMES]; 57 58 // 0 = ZERO_MV, MV 59 int8_t mode_deltas[MAX_MODE_LF_DELTAS]; 60 }; 61 62 // Need to align this structure so when it is declared and 63 // passed it can be loaded into vector registers. 64 typedef struct { 65 DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, mblim[SIMD_WIDTH]); 66 DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, lim[SIMD_WIDTH]); 67 DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, hev_thr[SIMD_WIDTH]); 68 } loop_filter_thresh; 69 70 typedef struct { 71 loop_filter_thresh lfthr[MAX_LOOP_FILTER + 1]; 72 uint8_t lvl[MAX_MB_PLANE][MAX_SEGMENTS][2][REF_FRAMES][MAX_MODE_LF_DELTAS]; 73 } loop_filter_info_n; 74 75 typedef struct AV1_DEBLOCKING_PARAMETERS { 76 // length of the filter applied to the outer edge 77 uint8_t filter_length; 78 // deblocking limits 79 const loop_filter_thresh *lfthr; 80 } AV1_DEBLOCKING_PARAMETERS; 81 82 typedef struct LoopFilterWorkerData { 83 YV12_BUFFER_CONFIG *frame_buffer; 84 struct AV1Common *cm; 85 struct macroblockd_plane planes[MAX_MB_PLANE]; 86 // TODO(Ranjit): When the filter functions are modified to use xd->lossless 87 // add lossless as a member here. 88 MACROBLOCKD *xd; 89 90 AV1_DEBLOCKING_PARAMETERS params_buf[MAX_MIB_SIZE]; 91 TX_SIZE tx_buf[MAX_MIB_SIZE]; 92 struct aom_internal_error_info error_info; 93 } LFWorkerData; 94 /*!\endcond */ 95 96 /* assorted loopfilter functions which get used elsewhere */ 97 struct AV1Common; 98 struct macroblockd; 99 struct AV1LfSyncData; 100 101 void av1_loop_filter_init(struct AV1Common *cm); 102 103 void av1_loop_filter_frame_init(struct AV1Common *cm, int plane_start, 104 int plane_end); 105 106 void av1_filter_block_plane_vert(const struct AV1Common *const cm, 107 const MACROBLOCKD *const xd, const int plane, 108 const MACROBLOCKD_PLANE *const plane_ptr, 109 const uint32_t mi_row, const uint32_t mi_col); 110 111 void av1_filter_block_plane_horz(const struct AV1Common *const cm, 112 const MACROBLOCKD *const xd, const int plane, 113 const MACROBLOCKD_PLANE *const plane_ptr, 114 const uint32_t mi_row, const uint32_t mi_col); 115 116 void av1_filter_block_plane_vert_opt( 117 const struct AV1Common *const cm, const MACROBLOCKD *const xd, 118 const MACROBLOCKD_PLANE *const plane_ptr, const uint32_t mi_row, 119 const uint32_t mi_col, AV1_DEBLOCKING_PARAMETERS *params_buf, 120 TX_SIZE *tx_buf, int num_mis_in_lpf_unit_height_log2); 121 122 void av1_filter_block_plane_vert_opt_chroma( 123 const struct AV1Common *const cm, const MACROBLOCKD *const xd, 124 const MACROBLOCKD_PLANE *const plane_ptr, const uint32_t mi_row, 125 const uint32_t mi_col, AV1_DEBLOCKING_PARAMETERS *params_buf, 126 TX_SIZE *tx_buf, int plane, bool joint_filter_chroma, 127 int num_mis_in_lpf_unit_height_log2); 128 129 void av1_filter_block_plane_horz_opt( 130 const struct AV1Common *const cm, const MACROBLOCKD *const xd, 131 const MACROBLOCKD_PLANE *const plane_ptr, const uint32_t mi_row, 132 const uint32_t mi_col, AV1_DEBLOCKING_PARAMETERS *params_buf, 133 TX_SIZE *tx_buf, int num_mis_in_lpf_unit_height_log2); 134 135 void av1_filter_block_plane_horz_opt_chroma( 136 const struct AV1Common *const cm, const MACROBLOCKD *const xd, 137 const MACROBLOCKD_PLANE *const plane_ptr, const uint32_t mi_row, 138 const uint32_t mi_col, AV1_DEBLOCKING_PARAMETERS *params_buf, 139 TX_SIZE *tx_buf, int plane, bool joint_filter_chroma, 140 int num_mis_in_lpf_unit_height_log2); 141 142 uint8_t av1_get_filter_level(const struct AV1Common *cm, 143 const loop_filter_info_n *lfi_n, const int dir_idx, 144 int plane, const MB_MODE_INFO *mbmi); 145 146 #ifdef __cplusplus 147 } // extern "C" 148 #endif 149 150 #endif // AOM_AV1_COMMON_AV1_LOOPFILTER_H_ 151