blob: c35c3b2dc483c396f495ed3f8f84d162d7e04441 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * 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 Xuc27fc142016-08-22 16:08:15 -070010 */
11
Yaowu Xuf883b422016-08-30 14:01:10 -070012#ifndef AV1_COMMON_LOOPFILTER_H_
13#define AV1_COMMON_LOOPFILTER_H_
Yaowu Xuc27fc142016-08-22 16:08:15 -070014
Tom Finegan60e653d2018-05-22 11:34:58 -070015#include "config/aom_config.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070016
Tom Finegan60e653d2018-05-22 11:34:58 -070017#include "aom_ports/mem.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070018#include "av1/common/blockd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019#include "av1/common/seg_common.h"
20
21#ifdef __cplusplus
22extern "C" {
23#endif
24
25#define MAX_LOOP_FILTER 63
26#define MAX_SHARPNESS 7
27
28#define SIMD_WIDTH 16
29
Yaowu Xuc27fc142016-08-22 16:08:15 -070030enum lf_path {
31 LF_PATH_420,
32 LF_PATH_444,
33 LF_PATH_SLOW,
34};
35
Cheng Chen10047242018-02-27 12:07:34 -080036#if LOOP_FILTER_BITMASK
37typedef struct {
38 uint64_t bits[4];
Cheng Chen8ab1f442018-04-27 18:01:52 -070039} FilterMask;
Cheng Chen10047242018-02-27 12:07:34 -080040
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.
51typedef struct {
Cheng Chen8ab1f442018-04-27 18:01:52 -070052 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];
Cheng Chen10047242018-02-27 12:07:34 -080058
59 // Y plane vertical edge and horizontal edge filter level
Cheng Chen30ea3922018-03-01 10:51:06 -080060 uint8_t lfl_y_hor[MI_SIZE_64X64][MI_SIZE_64X64];
61 uint8_t lfl_y_ver[MI_SIZE_64X64][MI_SIZE_64X64];
Cheng Chen10047242018-02-27 12:07:34 -080062
Cheng Chen8ab1f442018-04-27 18:01:52 -070063 // U plane vertical edge and horizontal edge filter level
64 uint8_t lfl_u_hor[MI_SIZE_64X64][MI_SIZE_64X64];
65 uint8_t lfl_u_ver[MI_SIZE_64X64][MI_SIZE_64X64];
Cheng Chen10047242018-02-27 12:07:34 -080066
Cheng Chen8ab1f442018-04-27 18:01:52 -070067 // V plane vertical edge and horizontal edge filter level
68 uint8_t lfl_v_hor[MI_SIZE_64X64][MI_SIZE_64X64];
69 uint8_t lfl_v_ver[MI_SIZE_64X64][MI_SIZE_64X64];
Cheng Chen10047242018-02-27 12:07:34 -080070} LoopFilterMask;
71
72// To determine whether to apply loop filtering at one transform block edge,
73// we need information of the neighboring transform block. Specifically,
74// in determining a vertical edge, we need the information of the tx block
75// to its left. For a horizontal edge, we need info of the tx block above it.
76// Thus, we need to record info of right column and bottom row of tx blocks.
77// We record the information of the neighboring superblock, when bitmask
78// building for a superblock is finished. And it will be used for next
79// superblock bitmask building.
80// Information includes:
81// ------------------------------------------------------------
Cheng Chen30ea3922018-03-01 10:51:06 -080082// MI_SIZE_64X64
Cheng Chen10047242018-02-27 12:07:34 -080083// Y tx_size above |--------------|
84// Y tx_size left |--------------|
85// UV tx_size above |--------------|
86// UV tx_size left |--------------|
87// Y level above |--------------|
88// Y level left |--------------|
89// U level above |--------------|
90// U level left |--------------|
91// V level above |--------------|
92// V level left |--------------|
93// skip |--------------|
94// ------------------------------------------------------------
95typedef struct {
Cheng Chen30ea3922018-03-01 10:51:06 -080096 TX_SIZE tx_size_y_above[MI_SIZE_64X64];
97 TX_SIZE tx_size_y_left[MI_SIZE_64X64];
98 TX_SIZE tx_size_uv_above[MI_SIZE_64X64];
99 TX_SIZE tx_size_uv_left[MI_SIZE_64X64];
100 uint8_t y_level_above[MI_SIZE_64X64];
101 uint8_t y_level_left[MI_SIZE_64X64];
102 uint8_t u_level_above[MI_SIZE_64X64];
103 uint8_t u_level_left[MI_SIZE_64X64];
104 uint8_t v_level_above[MI_SIZE_64X64];
105 uint8_t v_level_left[MI_SIZE_64X64];
106 uint8_t skip[MI_SIZE_64X64];
Cheng Chen10047242018-02-27 12:07:34 -0800107} LpfSuperblockInfo;
108#endif // LOOP_FILTER_BITMASK
109
Yaowu Xuc27fc142016-08-22 16:08:15 -0700110struct loopfilter {
Cheng Chen179479f2017-08-04 10:56:39 -0700111 int filter_level[2];
Cheng Chene94df5c2017-07-19 17:25:33 -0700112 int filter_level_u;
113 int filter_level_v;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700114
115 int sharpness_level;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700116
117 uint8_t mode_ref_delta_enabled;
118 uint8_t mode_ref_delta_update;
119
Sebastien Alaiwan365e6442017-10-16 11:35:00 +0200120 // 0 = Intra, Last, Last2+Last3,
121 // GF, BRF, ARF2, ARF
Zoe Liu27deb382018-03-27 15:13:56 -0700122 int8_t ref_deltas[REF_FRAMES];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700123
124 // 0 = ZERO_MV, MV
Yaowu Xu0fbe33d2017-08-31 09:34:29 -0700125 int8_t mode_deltas[MAX_MODE_LF_DELTAS];
Cheng Chen10047242018-02-27 12:07:34 -0800126
Deepa K Gc08f9492018-03-22 12:02:14 +0530127 int combine_vert_horz_lf;
128
Cheng Chen10047242018-02-27 12:07:34 -0800129#if LOOP_FILTER_BITMASK
130 LoopFilterMask *lfm;
131 size_t lfm_num;
132 int lfm_stride;
133 LpfSuperblockInfo neighbor_sb_lpf_info;
Cheng Chen30ea3922018-03-01 10:51:06 -0800134#endif // LOOP_FILTER_BITMASK
Yaowu Xuc27fc142016-08-22 16:08:15 -0700135};
136
137// Need to align this structure so when it is declared and
138// passed it can be loaded into vector registers.
139typedef struct {
140 DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, mblim[SIMD_WIDTH]);
141 DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, lim[SIMD_WIDTH]);
142 DECLARE_ALIGNED(SIMD_WIDTH, uint8_t, hev_thr[SIMD_WIDTH]);
143} loop_filter_thresh;
144
145typedef struct {
146 loop_filter_thresh lfthr[MAX_LOOP_FILTER + 1];
Deepa K G3cc31d52018-04-05 10:41:40 +0530147 uint8_t lvl[MAX_MB_PLANE][MAX_SEGMENTS][2][REF_FRAMES][MAX_MODE_LF_DELTAS];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700148} loop_filter_info_n;
149
Yaowu Xuc27fc142016-08-22 16:08:15 -0700150/* assorted loopfilter functions which get used elsewhere */
Yaowu Xuf883b422016-08-30 14:01:10 -0700151struct AV1Common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700152struct macroblockd;
Yaowu Xuf883b422016-08-30 14:01:10 -0700153struct AV1LfSyncData;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700154
Yaowu Xuf883b422016-08-30 14:01:10 -0700155void av1_loop_filter_init(struct AV1Common *cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700156
Deepa K G964e72e2018-05-16 16:56:01 +0530157void av1_loop_filter_frame_init(struct AV1Common *cm, int plane_start,
158 int plane_end);
159
Yaowu Xuf883b422016-08-30 14:01:10 -0700160void av1_loop_filter_frame(YV12_BUFFER_CONFIG *frame, struct AV1Common *cm,
Deepa K G3cc31d52018-04-05 10:41:40 +0530161 struct macroblockd *mbd, int plane_start,
162 int plane_end, int partial_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700163
Deepa K G964e72e2018-05-16 16:56:01 +0530164void av1_filter_block_plane_vert(const struct AV1Common *const cm,
165 const MACROBLOCKD *const xd, const int plane,
166 const MACROBLOCKD_PLANE *const plane_ptr,
167 const uint32_t mi_row, const uint32_t mi_col);
168
169void av1_filter_block_plane_horz(const struct AV1Common *const cm,
170 const MACROBLOCKD *const xd, const int plane,
171 const MACROBLOCKD_PLANE *const plane_ptr,
172 const uint32_t mi_row, const uint32_t mi_col);
173
Yaowu Xuc27fc142016-08-22 16:08:15 -0700174typedef struct LoopFilterWorkerData {
175 YV12_BUFFER_CONFIG *frame_buffer;
Yaowu Xuf883b422016-08-30 14:01:10 -0700176 struct AV1Common *cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700177 struct macroblockd_plane planes[MAX_MB_PLANE];
Deepa K G964e72e2018-05-16 16:56:01 +0530178 // TODO(Ranjit): When the filter functions are modified to use xd->lossless
179 // add lossless as a member here.
180 MACROBLOCKD *xd;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700181} LFWorkerData;
182
Deepa K G964e72e2018-05-16 16:56:01 +0530183#if LOOP_FILTER_BITMASK
Deepa K G964e72e2018-05-16 16:56:01 +0530184void av1_setup_bitmask(struct AV1Common *const cm, int mi_row, int mi_col,
185 int plane, int subsampling_x, int subsampling_y,
Cheng Chen8ab1f442018-04-27 18:01:52 -0700186 int row_end, int col_end);
Deepa K G964e72e2018-05-16 16:56:01 +0530187
Cheng Chen8ab1f442018-04-27 18:01:52 -0700188void av1_filter_block_plane_ver(struct AV1Common *const cm,
189 struct macroblockd_plane *const plane_ptr,
190 int pl, int mi_row, int mi_col);
Deepa K G964e72e2018-05-16 16:56:01 +0530191
Cheng Chen8ab1f442018-04-27 18:01:52 -0700192void av1_filter_block_plane_hor(struct AV1Common *const cm,
193 struct macroblockd_plane *const plane, int pl,
194 int mi_row, int mi_col);
Deepa K G964e72e2018-05-16 16:56:01 +0530195#endif
196
Yaowu Xuc27fc142016-08-22 16:08:15 -0700197#ifdef __cplusplus
198} // extern "C"
199#endif
200
Yaowu Xuf883b422016-08-30 14:01:10 -0700201#endif // AV1_COMMON_LOOPFILTER_H_