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
16extern "C" {
17#endif
19struct AV1_COMP;
20struct 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// 6. Threshold to identify if the q is in a relative high range.
68// Above this cutoff q, a stronger filtering is applied.
69// For a high q, the quantization throws away more information, and thus a
70// stronger filtering is less likely to distort the encoded quality, while a
71// stronger filtering could reduce bit rates.
72// Ror a low q, more details are expected to be retained. Filtering is thus
73// more conservative.
74#define TF_QINDEX_CUTOFF 128
75
76#define NOISE_ESTIMATION_EDGE_THRESHOLD 50
77
83typedef struct {
87 YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS];
103 struct scale_factors sf;
107 double noise_levels[MAX_MB_PLANE];
129
132// Sum and SSE source vs filtered frame difference returned by
133// temporal filter.
134typedef struct {
135 int64_t sum;
136 int64_t sse;
137} FRAME_DIFF;
138
139// Data related to temporal filtering.
140typedef struct {
141 // Source vs filtered frame error.
142 FRAME_DIFF diff;
143 // Pointer to temporary block info used to store state in temporal filtering
144 // process.
145 MB_MODE_INFO *tmp_mbmi;
146 // Pointer to accumulator buffer used in temporal filtering process.
147 uint32_t *accum;
148 // Pointer to count buffer used in temporal filtering process.
149 uint16_t *count;
150 // Pointer to predictor used in temporal filtering process.
151 uint8_t *pred;
152} TemporalFilterData;
153
154// Data related to temporal filter multi-thread synchronization.
155typedef struct {
156#if CONFIG_MULTITHREAD
157 // Mutex lock used for dispatching jobs.
158 pthread_mutex_t *mutex_;
159#endif // CONFIG_MULTITHREAD
160 // Next temporal filter block row to be filtered.
161 int next_tf_row;
162} AV1TemporalFilterSync;
163
164// Estimates noise level from a given frame using a single plane (Y, U, or V).
165// This is an adaptation of the mehtod in the following paper:
166// Shen-Chuan Tai, Shih-Ming Yang, "A fast method for image noise
167// estimation using Laplacian operator and adaptive edge detection",
168// Proc. 3rd International Symposium on Communications, Control and
169// Signal Processing, 2008, St Julians, Malta.
170// Inputs:
171// frame: Pointer to the frame to estimate noise level from.
172// plane: Index of the plane used for noise estimation. Commonly, 0 for
173// Y-plane, 1 for U-plane, and 2 for V-plane.
174// bit_depth: Actual bit-depth instead of the encoding bit-depth of the frame.
175// Returns:
176// The estimated noise, or -1.0 if there are too few smooth pixels.
177double av1_estimate_noise_from_single_plane(const YV12_BUFFER_CONFIG *frame,
178 const int plane,
179 const int bit_depth);
193void av1_tf_do_filtering_row(struct AV1_COMP *cpi, struct ThreadData *td,
194 int mb_row);
195
221int av1_temporal_filter(struct AV1_COMP *cpi,
222 const int filter_frame_lookahead_idx,
223 FRAME_UPDATE_TYPE update_type, int is_forward_keyframe,
224 int *show_existing_arf);
225
227// Helper function to get `q` used for encoding.
228int av1_get_q(const struct AV1_COMP *cpi);
229
230// Allocates memory for members of TemporalFilterData.
231// Inputs:
232// tf_data: Pointer to the structure containing temporal filter related data.
233// num_pels: Number of pixels in the block across all planes.
234// is_high_bitdepth: Whether the frame is high-bitdepth or not.
235// Returns:
236// Nothing will be returned. But the contents of tf_data will be modified.
237static AOM_INLINE void tf_alloc_and_reset_data(TemporalFilterData *tf_data,
238 int num_pels,
239 int is_high_bitdepth) {
240 tf_data->tmp_mbmi = (MB_MODE_INFO *)malloc(sizeof(*tf_data->tmp_mbmi));
241 memset(tf_data->tmp_mbmi, 0, sizeof(*tf_data->tmp_mbmi));
242 tf_data->accum =
243 (uint32_t *)aom_memalign(16, num_pels * sizeof(*tf_data->accum));
244 tf_data->count =
245 (uint16_t *)aom_memalign(16, num_pels * sizeof(*tf_data->count));
246 memset(&tf_data->diff, 0, sizeof(tf_data->diff));
247 if (is_high_bitdepth)
248 tf_data->pred = CONVERT_TO_BYTEPTR(
249 aom_memalign(32, num_pels * 2 * sizeof(*tf_data->pred)));
250 else
251 tf_data->pred =
252 (uint8_t *)aom_memalign(32, num_pels * sizeof(*tf_data->pred));
253}
254
255// Setup macroblockd params for temporal filtering process.
256// Inputs:
257// mbd: Pointer to the block for filtering.
258// tf_data: Pointer to the structure containing temporal filter related data.
259// scale: Scaling factor.
260// Returns:
261// Nothing will be returned. Contents of mbd will be modified.
262static AOM_INLINE void tf_setup_macroblockd(MACROBLOCKD *mbd,
263 TemporalFilterData *tf_data,
264 const struct scale_factors *scale) {
265 mbd->block_ref_scale_factors[0] = scale;
266 mbd->block_ref_scale_factors[1] = scale;
267 mbd->mi = &tf_data->tmp_mbmi;
268 mbd->mi[0]->motion_mode = SIMPLE_TRANSLATION;
269}
270
271// Deallocates the memory allocated for members of TemporalFilterData.
272// Inputs:
273// tf_data: Pointer to the structure containing temporal filter related data.
274// is_high_bitdepth: Whether the frame is high-bitdepth or not.
275// Returns:
276// Nothing will be returned.
277static AOM_INLINE void tf_dealloc_data(TemporalFilterData *tf_data,
278 int is_high_bitdepth) {
279 if (is_high_bitdepth)
280 tf_data->pred = (uint8_t *)CONVERT_TO_SHORTPTR(tf_data->pred);
281 free(tf_data->tmp_mbmi);
282 aom_free(tf_data->accum);
283 aom_free(tf_data->count);
284 aom_free(tf_data->pred);
285}
286
287// Saves the state prior to temporal filter process.
288// Inputs:
289// mbd: Pointer to the block for filtering.
290// input_mbmi: Backup block info to save input state.
291// input_buffer: Backup buffer pointer to save input state.
292// num_planes: Number of planes.
293// Returns:
294// Nothing will be returned. Contents of input_mbmi and input_buffer will be
295// modified.
296static INLINE void tf_save_state(MACROBLOCKD *mbd, MB_MODE_INFO ***input_mbmi,
297 uint8_t **input_buffer, int num_planes) {
298 for (int i = 0; i < num_planes; i++) {
299 input_buffer[i] = mbd->plane[i].pre[0].buf;
300 }
301 *input_mbmi = mbd->mi;
302}
303
304// Restores the initial state after temporal filter process.
305// Inputs:
306// mbd: Pointer to the block for filtering.
307// input_mbmi: Backup block info from where input state is restored.
308// input_buffer: Backup buffer pointer from where input state is restored.
309// num_planes: Number of planes.
310// Returns:
311// Nothing will be returned. Contents of mbd will be modified.
312static INLINE void tf_restore_state(MACROBLOCKD *mbd, MB_MODE_INFO **input_mbmi,
313 uint8_t **input_buffer, int num_planes) {
314 for (int i = 0; i < num_planes; i++) {
315 mbd->plane[i].pre[0].buf = input_buffer[i];
316 }
317 mbd->mi = input_mbmi;
318}
319
321#ifdef __cplusplus
322} // extern "C"
323#endif
324
325#endif // AOM_AV1_ENCODER_TEMPORAL_FILTER_H_
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...
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:762
Stores the prediction/txfm mode of the current coding block.
Definition: blockd.h:222
MOTION_MODE motion_mode
The motion mode used by the inter prediction.
Definition: blockd.h:250
Parameters related to temporal filtering.
Definition: temporal_filter.h:83
int q_factor
Definition: temporal_filter.h:127
int num_pels
Definition: temporal_filter.h:111
int num_frames
Definition: temporal_filter.h:91
int mb_rows
Definition: temporal_filter.h:115
int mb_cols
Definition: temporal_filter.h:119
int is_highbitdepth
Definition: temporal_filter.h:123
int check_show_existing
Definition: temporal_filter.h:99
int filter_frame_idx
Definition: temporal_filter.h:95
Variables related to current coding block.
Definition: blockd.h:577
struct macroblockd_plane plane[3]
Definition: blockd.h:613
const struct scale_factors * block_ref_scale_factors[2]
Definition: blockd.h:694
MB_MODE_INFO ** mi
Definition: blockd.h:624
YV12 frame buffer data structure.
Definition: yv12config.h:38