AOMedia AV1 Codec: av1/encoder/temporal_filter.h Source File

| AOMedia AV1 Codec

temporal_filter.h
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_ENCODER_TEMPORAL_FILTER_H_
13 #define AOM_AV1_ENCODER_TEMPORAL_FILTER_H_
14
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
19 struct AV1_COMP;
20 struct ThreadData;
21 // TODO(any): These two variables are only used in avx2, sse2, sse4
22 // implementations, where the block size is still hard coded. This should be
23 // fixed to align with the c implementation.
24 #define BH 32
25 #define BW 32
26
27 // Block size used in temporal filtering.
28 #define TF_BLOCK_SIZE BLOCK_32X32
29
30 // Window size for temporal filtering.
31 #define TF_WINDOW_LENGTH 5
32
33 // Hyper-parameters used to compute filtering weight. These hyper-parameters can
34 // be tuned for a better performance.
35 // 0. A scale factor used in temporal filtering to raise the filter weight from
36 // `double` with range [0, 1] to `int` with range [0, 1000].
37 #define TF_WEIGHT_SCALE 1000
38 // 1. Weight factor used to balance the weighted-average between window error
39 // and block error. The weight is for window error while the weight for block
40 // error is always set as 1.
41 #define TF_WINDOW_BLOCK_BALANCE_WEIGHT 5
42 // 2. Threshold for using q to adjust the filtering weight. Concretely, when
43 // using a small q (high bitrate), we would like to reduce the filtering
44 // strength such that more detailed information can be preserved. Hence, when
45 // q is smaller than this threshold, we will adjust the filtering weight
46 // based on the q-value.
47 #define TF_Q_DECAY_THRESHOLD 20
48 // 3. Normalization factor used to normalize the motion search error. Since the
49 // motion search error can be large and uncontrollable, we will simply
50 // normalize it before using it to compute the filtering weight.
51 #define TF_SEARCH_ERROR_NORM_WEIGHT 20
52 // 4. Threshold for using `arnr_strength` to adjust the filtering strength.
53 // Concretely, users can use `arnr_strength` arguments to control the
54 // strength of temporal filtering. When `arnr_strength` is small enough (
55 // i.e., smaller than this threshold), we will adjust the filtering weight
56 // based on the strength value.
57 #define TF_STRENGTH_THRESHOLD 4
58 // 5. Threshold for using motion search distance to adjust the filtering weight.
59 // Concretely, larger motion search vector leads to a higher probability of
60 // unreliable search. Hence, we would like to reduce the filtering strength
61 // when the distance is large enough. Considering that the distance actually
62 // relies on the frame size, this threshold is also a resolution-based
63 // threshold. Taking 720p videos as an instance, if this field equals to 0.1,
64 // then the actual threshold will be 720 * 0.1 = 72. Similarly, the threshold
65 // for 360p videos will be 360 * 0.1 = 36.
66 #define TF_SEARCH_DISTANCE_THRESHOLD 0.1
67
68 #define NOISE_ESTIMATION_EDGE_THRESHOLD 50
69
75 typedef struct {
79 YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS];
83 int num_frames;
87 int filter_frame_idx;
91 int check_show_existing;
95 struct scale_factors sf;
99 double noise_levels[MAX_MB_PLANE];
103 int num_pels;
107 int mb_rows;
111 int mb_cols;
115 int is_highbitdepth;
119 int q_factor;
120 } TemporalFilterCtx;
121
124 // Sum and SSE source vs filtered frame difference returned by
125 // temporal filter.
126 typedef struct {
127 int64_t sum;
128 int64_t sse;
129 } FRAME_DIFF;
130
131 // Data related to temporal filtering.
132 typedef struct {
133 // Source vs filtered frame error.
134 FRAME_DIFF diff;
135 // Pointer to temporary block info used to store state in temporal filtering
136 // process.
137 MB_MODE_INFO *tmp_mbmi;
138 // Pointer to accumulator buffer used in temporal filtering process.
139 uint32_t *accum;
140 // Pointer to count buffer used in temporal filtering process.
141 uint16_t *count;
142 // Pointer to predictor used in temporal filtering process.
143 uint8_t *pred;
144 } TemporalFilterData;
145
146 // Data related to temporal filter multi-thread synchronization.
147 typedef struct {
148 #if CONFIG_MULTITHREAD
149 // Mutex lock used for dispatching jobs.
150 pthread_mutex_t *mutex_;
151 #endif // CONFIG_MULTITHREAD
152 // Next temporal filter block row to be filtered.
153 int next_tf_row;
154 } AV1TemporalFilterSync;
155
156 // Estimates noise level from a given frame using a single plane (Y, U, or V).
157 // This is an adaptation of the mehtod in the following paper:
158 // Shen-Chuan Tai, Shih-Ming Yang, "A fast method for image noise
159 // estimation using Laplacian operator and adaptive edge detection",
160 // Proc. 3rd International Symposium on Communications, Control and
161 // Signal Processing, 2008, St Julians, Malta.
162 // Inputs:
163 // frame: Pointer to the frame to estimate noise level from.
164 // plane: Index of the plane used for noise estimation. Commonly, 0 for
165 // Y-plane, 1 for U-plane, and 2 for V-plane.
166 // bit_depth: Actual bit-depth instead of the encoding bit-depth of the frame.
167 // Returns:
168 // The estimated noise, or -1.0 if there are too few smooth pixels.
169 double av1_estimate_noise_from_single_plane(const YV12_BUFFER_CONFIG *frame,
170 const int plane,
171 const int bit_depth);
185 void av1_tf_do_filtering_row(struct AV1_COMP *cpi, struct ThreadData *td,
186 int mb_row);
187
213 int av1_temporal_filter(struct AV1_COMP *cpi,
214 const int filter_frame_lookahead_idx,
215 FRAME_UPDATE_TYPE update_type, int is_forward_keyframe,
216 int *show_existing_arf);
217
219 // Helper function to get `q` used for encoding.
220 int av1_get_q(const struct AV1_COMP *cpi);
221
222 // Allocates memory for members of TemporalFilterData.
223 // Inputs:
224 // tf_data: Pointer to the structure containing temporal filter related data.
225 // num_pels: Number of pixels in the block across all planes.
226 // is_high_bitdepth: Whether the frame is high-bitdepth or not.
227 // Returns:
228 // Nothing will be returned. But the contents of tf_data will be modified.
229 static AOM_INLINE void tf_alloc_and_reset_data(TemporalFilterData *tf_data,
230 int num_pels,
231 int is_high_bitdepth) {
232 tf_data->tmp_mbmi = (MB_MODE_INFO *)malloc(sizeof(*tf_data->tmp_mbmi));
233 memset(tf_data->tmp_mbmi, 0, sizeof(*tf_data->tmp_mbmi));
234 tf_data->accum =
235 (uint32_t *)aom_memalign(16, num_pels * sizeof(*tf_data->accum));
236 tf_data->count =
237 (uint16_t *)aom_memalign(16, num_pels * sizeof(*tf_data->count));
238 memset(&tf_data->diff, 0, sizeof(tf_data->diff));
239 if (is_high_bitdepth)
240 tf_data->pred = CONVERT_TO_BYTEPTR(
241 aom_memalign(32, num_pels * 2 * sizeof(*tf_data->pred)));
242 else
243 tf_data->pred =
244 (uint8_t *)aom_memalign(32, num_pels * sizeof(*tf_data->pred));
245 }
246
247 // Setup macroblockd params for temporal filtering process.
248 // Inputs:
249 // mbd: Pointer to the block for filtering.
250 // tf_data: Pointer to the structure containing temporal filter related data.
251 // scale: Scaling factor.
252 // Returns:
253 // Nothing will be returned. Contents of mbd will be modified.
254 static AOM_INLINE void tf_setup_macroblockd(MACROBLOCKD *mbd,
255 TemporalFilterData *tf_data,
256 const struct scale_factors *scale) {
257 mbd->block_ref_scale_factors[0] = scale;
258 mbd->block_ref_scale_factors[1] = scale;
259 mbd->mi = &tf_data->tmp_mbmi;
260 mbd->mi[0]->motion_mode = SIMPLE_TRANSLATION;
261 }
262
263 // Deallocates the memory allocated for members of TemporalFilterData.
264 // Inputs:
265 // tf_data: Pointer to the structure containing temporal filter related data.
266 // is_high_bitdepth: Whether the frame is high-bitdepth or not.
267 // Returns:
268 // Nothing will be returned.
269 static AOM_INLINE void tf_dealloc_data(TemporalFilterData *tf_data,
270 int is_high_bitdepth) {
271 if (is_high_bitdepth)
272 tf_data->pred = (uint8_t *)CONVERT_TO_SHORTPTR(tf_data->pred);
273 free(tf_data->tmp_mbmi);
274 aom_free(tf_data->accum);
275 aom_free(tf_data->count);
276 aom_free(tf_data->pred);
277 }
278
279 // Helper function to compute number of blocks on either side of the frame.
280 static INLINE int get_num_blocks(const int frame_length, const int mb_length) {
281 return (frame_length + mb_length - 1) / mb_length;
282 }
283
284 // Saves the state prior to temporal filter process.
285 // Inputs:
286 // mbd: Pointer to the block for filtering.
287 // input_mbmi: Backup block info to save input state.
288 // input_buffer: Backup buffer pointer to save input state.
289 // num_planes: Number of planes.
290 // Returns:
291 // Nothing will be returned. Contents of input_mbmi and input_buffer will be
292 // modified.
293 static INLINE void tf_save_state(MACROBLOCKD *mbd, MB_MODE_INFO ***input_mbmi,
294 uint8_t **input_buffer, int num_planes) {
295 for (int i = 0; i < num_planes; i++) {
296 input_buffer[i] = mbd->plane[i].pre[0].buf;
297 }
298 *input_mbmi = mbd->mi;
299 }
300
301 // Restores the initial state after temporal filter process.
302 // Inputs:
303 // mbd: Pointer to the block for filtering.
304 // input_mbmi: Backup block info from where input state is restored.
305 // input_buffer: Backup buffer pointer from where input state is restored.
306 // num_planes: Number of planes.
307 // Returns:
308 // Nothing will be returned. Contents of mbd will be modified.
309 static INLINE void tf_restore_state(MACROBLOCKD *mbd, MB_MODE_INFO **input_mbmi,
310 uint8_t **input_buffer, int num_planes) {
311 for (int i = 0; i < num_planes; i++) {
312 mbd->plane[i].pre[0].buf = input_buffer[i];
313 }
314 mbd->mi = input_mbmi;
315 }
316
318 #ifdef __cplusplus
319 } // extern "C"
320 #endif
321
322 #endif // AOM_AV1_ENCODER_TEMPORAL_FILTER_H_
av1_temporal_filter
int av1_temporal_filter(struct AV1_COMP *cpi, const int filter_frame_lookahead_idx, FRAME_UPDATE_TYPE update_type, int is_forward_keyframe, int *show_existing_arf)
Performs temporal filtering if needed on a source frame. For example to create a filtered alternate r...
av1_tf_do_filtering_row
void av1_tf_do_filtering_row(struct AV1_COMP *cpi, struct ThreadData *td, int mb_row)
Does temporal filter for a given macroblock row.
Definition: temporal_filter.c:755
AV1_COMP
Top level encoder structure.
Definition: encoder.h:2095
MB_MODE_INFO
Stores the prediction/txfm mode of the current coding block.
Definition: blockd.h:216
MB_MODE_INFO::motion_mode
MOTION_MODE motion_mode
The motion mode used by the inter prediction.
Definition: blockd.h:244
TemporalFilterCtx
Parameters related to temporal filtering.
Definition: temporal_filter.h:75
TemporalFilterCtx::q_factor
int q_factor
Definition: temporal_filter.h:119
TemporalFilterCtx::num_pels
int num_pels
Definition: temporal_filter.h:103
TemporalFilterCtx::num_frames
int num_frames
Definition: temporal_filter.h:83
TemporalFilterCtx::mb_rows
int mb_rows
Definition: temporal_filter.h:107
TemporalFilterCtx::mb_cols
int mb_cols
Definition: temporal_filter.h:111
TemporalFilterCtx::is_highbitdepth
int is_highbitdepth
Definition: temporal_filter.h:115
TemporalFilterCtx::check_show_existing
int check_show_existing
Definition: temporal_filter.h:91
TemporalFilterCtx::filter_frame_idx
int filter_frame_idx
Definition: temporal_filter.h:87
macroblockd
Variables related to current coding block.
Definition: blockd.h:568
macroblockd::plane
struct macroblockd_plane plane[3]
Definition: blockd.h:604
macroblockd::block_ref_scale_factors
const struct scale_factors * block_ref_scale_factors[2]
Definition: blockd.h:685
macroblockd::mi
MB_MODE_INFO ** mi
Definition: blockd.h:615
yv12_buffer_config
YV12 frame buffer data structure.
Definition: yv12config.h:38