Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame^] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 2ab7ff0 | 2016-09-02 12:04:54 -0700 | [diff] [blame^] | 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. |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 10 | */ |
| 11 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 12 | #ifndef AV1_COMMON_LOOPFILTER_H_ |
| 13 | #define AV1_COMMON_LOOPFILTER_H_ |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 14 | |
| 15 | #include "aom_ports/mem.h" |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 16 | #include "./aom_config.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 17 | |
| 18 | #include "av1/common/blockd.h" |
| 19 | #include "av1/common/restoration.h" |
| 20 | #include "av1/common/seg_common.h" |
| 21 | |
| 22 | #ifdef __cplusplus |
| 23 | extern "C" { |
| 24 | #endif |
| 25 | |
| 26 | #define MAX_LOOP_FILTER 63 |
| 27 | #define MAX_SHARPNESS 7 |
| 28 | |
| 29 | #define SIMD_WIDTH 16 |
| 30 | |
| 31 | #define MAX_MODE_LF_DELTAS 2 |
| 32 | |
| 33 | enum lf_path { |
| 34 | LF_PATH_420, |
| 35 | LF_PATH_444, |
| 36 | LF_PATH_SLOW, |
| 37 | }; |
| 38 | |
| 39 | struct loopfilter { |
| 40 | int filter_level; |
| 41 | |
| 42 | int sharpness_level; |
| 43 | int last_sharpness_level; |
| 44 | |
| 45 | uint8_t mode_ref_delta_enabled; |
| 46 | uint8_t mode_ref_delta_update; |
| 47 | |
| 48 | // 0 = Intra, Last, Last2+Last3(CONFIG_EXT_REFS), |
| 49 | // GF, BRF(CONFIG_EXT_REFS), ARF |
| 50 | signed char ref_deltas[TOTAL_REFS_PER_FRAME]; |
| 51 | signed char last_ref_deltas[TOTAL_REFS_PER_FRAME]; |
| 52 | |
| 53 | // 0 = ZERO_MV, MV |
| 54 | signed char mode_deltas[MAX_MODE_LF_DELTAS]; |
| 55 | signed char last_mode_deltas[MAX_MODE_LF_DELTAS]; |
| 56 | }; |
| 57 | |
| 58 | // Need to align this structure so when it is declared and |
| 59 | // passed it can be loaded into vector registers. |
| 60 | typedef struct { |
| 61 | DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, mblim[SIMD_WIDTH]); |
| 62 | DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, lim[SIMD_WIDTH]); |
| 63 | DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, hev_thr[SIMD_WIDTH]); |
| 64 | } loop_filter_thresh; |
| 65 | |
| 66 | typedef struct { |
| 67 | loop_filter_thresh lfthr[MAX_LOOP_FILTER + 1]; |
| 68 | uint8_t lvl[MAX_SEGMENTS][TOTAL_REFS_PER_FRAME][MAX_MODE_LF_DELTAS]; |
| 69 | } loop_filter_info_n; |
| 70 | |
| 71 | // This structure holds bit masks for all 8x8 blocks in a 64x64 region. |
| 72 | // Each 1 bit represents a position in which we want to apply the loop filter. |
| 73 | // Left_ entries refer to whether we apply a filter on the border to the |
| 74 | // left of the block. Above_ entries refer to whether or not to apply a |
| 75 | // filter on the above border. Int_ entries refer to whether or not to |
| 76 | // apply borders on the 4x4 edges within the 8x8 block that each bit |
| 77 | // represents. |
| 78 | // Since each transform is accompanied by a potentially different type of |
| 79 | // loop filter there is a different entry in the array for each transform size. |
| 80 | typedef struct { |
| 81 | uint64_t left_y[TX_SIZES]; |
| 82 | uint64_t above_y[TX_SIZES]; |
| 83 | uint64_t int_4x4_y; |
| 84 | uint16_t left_uv[TX_SIZES]; |
| 85 | uint16_t above_uv[TX_SIZES]; |
| 86 | uint16_t left_int_4x4_uv; |
| 87 | uint16_t above_int_4x4_uv; |
| 88 | uint8_t lfl_y[MAX_MIB_SIZE][MAX_MIB_SIZE]; |
| 89 | uint8_t lfl_uv[MAX_MIB_SIZE / 2][MAX_MIB_SIZE / 2]; |
| 90 | } LOOP_FILTER_MASK; |
| 91 | |
| 92 | /* assorted loopfilter functions which get used elsewhere */ |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 93 | struct AV1Common; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 94 | struct macroblockd; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 95 | struct AV1LfSyncData; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 96 | |
| 97 | // This function sets up the bit masks for the entire 64x64 region represented |
| 98 | // by mi_row, mi_col. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 99 | void av1_setup_mask(struct AV1Common *const cm, const int mi_row, |
| 100 | const int mi_col, MODE_INFO **mi_8x8, |
| 101 | const int mode_info_stride, LOOP_FILTER_MASK *lfm); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 102 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 103 | void av1_filter_block_plane_ss00(struct AV1Common *const cm, |
| 104 | struct macroblockd_plane *const plane, |
| 105 | int mi_row, LOOP_FILTER_MASK *lfm); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 106 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 107 | void av1_filter_block_plane_ss11(struct AV1Common *const cm, |
| 108 | struct macroblockd_plane *const plane, |
| 109 | int mi_row, LOOP_FILTER_MASK *lfm); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 110 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 111 | void av1_filter_block_plane_non420(struct AV1Common *cm, |
| 112 | struct macroblockd_plane *plane, |
| 113 | MODE_INFO **mi_8x8, int mi_row, int mi_col); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 114 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 115 | void av1_loop_filter_init(struct AV1Common *cm); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 116 | |
| 117 | // Update the loop filter for the current frame. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 118 | // This should be called before av1_loop_filter_rows(), |
| 119 | // av1_loop_filter_frame() |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 120 | // calls this function directly. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 121 | void av1_loop_filter_frame_init(struct AV1Common *cm, int default_filt_lvl); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 122 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 123 | void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm, |
| 124 | struct macroblockd *mbd, int filter_level, |
| 125 | int y_only, int partial_frame); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 126 | |
| 127 | // Apply the loop filter to [start, stop) macro block rows in frame_buffer. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 128 | void av1_loop_filter_rows(YV12_BUFFER_CONFIG *frame_buffer, |
| 129 | struct AV1Common *cm, |
| 130 | struct macroblockd_plane planes[MAX_MB_PLANE], |
| 131 | int start, int stop, int y_only); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 132 | |
| 133 | typedef struct LoopFilterWorkerData { |
| 134 | YV12_BUFFER_CONFIG *frame_buffer; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 135 | struct AV1Common *cm; |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 136 | struct macroblockd_plane planes[MAX_MB_PLANE]; |
| 137 | |
| 138 | int start; |
| 139 | int stop; |
| 140 | int y_only; |
| 141 | } LFWorkerData; |
| 142 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 143 | void av1_loop_filter_data_reset( |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 144 | LFWorkerData *lf_data, YV12_BUFFER_CONFIG *frame_buffer, |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 145 | struct AV1Common *cm, const struct macroblockd_plane planes[MAX_MB_PLANE]); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 146 | |
| 147 | // Operates on the rows described by 'lf_data'. |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 148 | int av1_loop_filter_worker(LFWorkerData *const lf_data, void *unused); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 149 | #ifdef __cplusplus |
| 150 | } // extern "C" |
| 151 | #endif |
| 152 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 153 | #endif // AV1_COMMON_LOOPFILTER_H_ |