xref: /aosp_15_r20/external/libaom/aom_dsp/noise_model.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2017, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker 
12*77c1e3ccSAndroid Build Coastguard Worker #ifndef AOM_AOM_DSP_NOISE_MODEL_H_
13*77c1e3ccSAndroid Build Coastguard Worker #define AOM_AOM_DSP_NOISE_MODEL_H_
14*77c1e3ccSAndroid Build Coastguard Worker 
15*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus
16*77c1e3ccSAndroid Build Coastguard Worker extern "C" {
17*77c1e3ccSAndroid Build Coastguard Worker #endif  // __cplusplus
18*77c1e3ccSAndroid Build Coastguard Worker 
19*77c1e3ccSAndroid Build Coastguard Worker #include <stdint.h>
20*77c1e3ccSAndroid Build Coastguard Worker #include "aom_dsp/grain_params.h"
21*77c1e3ccSAndroid Build Coastguard Worker #include "aom_ports/mem.h"
22*77c1e3ccSAndroid Build Coastguard Worker #include "aom_scale/yv12config.h"
23*77c1e3ccSAndroid Build Coastguard Worker 
24*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Wrapper of data required to represent linear system of eqns and soln.
25*77c1e3ccSAndroid Build Coastguard Worker  */
26*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
27*77c1e3ccSAndroid Build Coastguard Worker   double *A;
28*77c1e3ccSAndroid Build Coastguard Worker   double *b;
29*77c1e3ccSAndroid Build Coastguard Worker   double *x;
30*77c1e3ccSAndroid Build Coastguard Worker   int n;
31*77c1e3ccSAndroid Build Coastguard Worker } aom_equation_system_t;
32*77c1e3ccSAndroid Build Coastguard Worker 
33*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Representation of a piecewise linear curve
34*77c1e3ccSAndroid Build Coastguard Worker  *
35*77c1e3ccSAndroid Build Coastguard Worker  * Holds n points as (x, y) pairs, that store the curve.
36*77c1e3ccSAndroid Build Coastguard Worker  */
37*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
38*77c1e3ccSAndroid Build Coastguard Worker   double (*points)[2];
39*77c1e3ccSAndroid Build Coastguard Worker   int num_points;
40*77c1e3ccSAndroid Build Coastguard Worker } aom_noise_strength_lut_t;
41*77c1e3ccSAndroid Build Coastguard Worker 
42*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Init the noise strength lut with the given number of points*/
43*77c1e3ccSAndroid Build Coastguard Worker int aom_noise_strength_lut_init(aom_noise_strength_lut_t *lut, int num_points);
44*77c1e3ccSAndroid Build Coastguard Worker 
45*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Frees the noise strength lut. */
46*77c1e3ccSAndroid Build Coastguard Worker void aom_noise_strength_lut_free(aom_noise_strength_lut_t *lut);
47*77c1e3ccSAndroid Build Coastguard Worker 
48*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Evaluate the lut at the point x.
49*77c1e3ccSAndroid Build Coastguard Worker  *
50*77c1e3ccSAndroid Build Coastguard Worker  * \param[in] lut  The lut data.
51*77c1e3ccSAndroid Build Coastguard Worker  * \param[in] x    The coordinate to evaluate the lut.
52*77c1e3ccSAndroid Build Coastguard Worker  */
53*77c1e3ccSAndroid Build Coastguard Worker double aom_noise_strength_lut_eval(const aom_noise_strength_lut_t *lut,
54*77c1e3ccSAndroid Build Coastguard Worker                                    double x);
55*77c1e3ccSAndroid Build Coastguard Worker 
56*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Helper struct to model noise strength as a function of intensity.
57*77c1e3ccSAndroid Build Coastguard Worker  *
58*77c1e3ccSAndroid Build Coastguard Worker  * Internally, this structure holds a representation of a linear system
59*77c1e3ccSAndroid Build Coastguard Worker  * of equations that models noise strength (standard deviation) as a
60*77c1e3ccSAndroid Build Coastguard Worker  * function of intensity. The mapping is initially stored using a
61*77c1e3ccSAndroid Build Coastguard Worker  * piecewise representation with evenly spaced bins that cover the entire
62*77c1e3ccSAndroid Build Coastguard Worker  * domain from [min_intensity, max_intensity]. Each observation (x,y) gives a
63*77c1e3ccSAndroid Build Coastguard Worker  * constraint of the form:
64*77c1e3ccSAndroid Build Coastguard Worker  *   y_{i} (1 - a) + y_{i+1} a = y
65*77c1e3ccSAndroid Build Coastguard Worker  * where y_{i} is the value of bin i and x_{i} <= x <= x_{i+1} and
66*77c1e3ccSAndroid Build Coastguard Worker  * a = x/(x_{i+1} - x{i}). The equation system holds the corresponding
67*77c1e3ccSAndroid Build Coastguard Worker  * normal equations.
68*77c1e3ccSAndroid Build Coastguard Worker  *
69*77c1e3ccSAndroid Build Coastguard Worker  * As there may be missing data, the solution is regularized to get a
70*77c1e3ccSAndroid Build Coastguard Worker  * complete set of values for the bins. A reduced representation after
71*77c1e3ccSAndroid Build Coastguard Worker  * solving can be obtained by getting the corresponding noise_strength_lut_t.
72*77c1e3ccSAndroid Build Coastguard Worker  */
73*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
74*77c1e3ccSAndroid Build Coastguard Worker   aom_equation_system_t eqns;
75*77c1e3ccSAndroid Build Coastguard Worker   double min_intensity;
76*77c1e3ccSAndroid Build Coastguard Worker   double max_intensity;
77*77c1e3ccSAndroid Build Coastguard Worker   int num_bins;
78*77c1e3ccSAndroid Build Coastguard Worker   int num_equations;
79*77c1e3ccSAndroid Build Coastguard Worker   double total;
80*77c1e3ccSAndroid Build Coastguard Worker } aom_noise_strength_solver_t;
81*77c1e3ccSAndroid Build Coastguard Worker 
82*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Initializes the noise solver with the given number of bins.
83*77c1e3ccSAndroid Build Coastguard Worker  *
84*77c1e3ccSAndroid Build Coastguard Worker  * Returns 0 if initialization fails.
85*77c1e3ccSAndroid Build Coastguard Worker  *
86*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  solver    The noise solver to be initialized.
87*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  num_bins  Number of bins to use in the internal representation.
88*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  bit_depth The bit depth used to derive {min,max}_intensity.
89*77c1e3ccSAndroid Build Coastguard Worker  */
90*77c1e3ccSAndroid Build Coastguard Worker int aom_noise_strength_solver_init(aom_noise_strength_solver_t *solver,
91*77c1e3ccSAndroid Build Coastguard Worker                                    int num_bins, int bit_depth);
92*77c1e3ccSAndroid Build Coastguard Worker void aom_noise_strength_solver_free(aom_noise_strength_solver_t *solver);
93*77c1e3ccSAndroid Build Coastguard Worker 
94*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Gets the x coordinate of bin i.
95*77c1e3ccSAndroid Build Coastguard Worker  *
96*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  i  The bin whose coordinate to query.
97*77c1e3ccSAndroid Build Coastguard Worker  */
98*77c1e3ccSAndroid Build Coastguard Worker double aom_noise_strength_solver_get_center(
99*77c1e3ccSAndroid Build Coastguard Worker     const aom_noise_strength_solver_t *solver, int i);
100*77c1e3ccSAndroid Build Coastguard Worker 
101*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Add an observation of the block mean intensity to its noise strength.
102*77c1e3ccSAndroid Build Coastguard Worker  *
103*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  block_mean  The average block intensity,
104*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  noise_std   The observed noise strength.
105*77c1e3ccSAndroid Build Coastguard Worker  */
106*77c1e3ccSAndroid Build Coastguard Worker void aom_noise_strength_solver_add_measurement(
107*77c1e3ccSAndroid Build Coastguard Worker     aom_noise_strength_solver_t *solver, double block_mean, double noise_std);
108*77c1e3ccSAndroid Build Coastguard Worker 
109*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Solves the current set of equations for the noise strength. */
110*77c1e3ccSAndroid Build Coastguard Worker int aom_noise_strength_solver_solve(aom_noise_strength_solver_t *solver);
111*77c1e3ccSAndroid Build Coastguard Worker 
112*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Fits a reduced piecewise linear lut to the internal solution
113*77c1e3ccSAndroid Build Coastguard Worker  *
114*77c1e3ccSAndroid Build Coastguard Worker  * \param[in] max_num_points  The maximum number of output points
115*77c1e3ccSAndroid Build Coastguard Worker  * \param[out] lut  The output piecewise linear lut.
116*77c1e3ccSAndroid Build Coastguard Worker  */
117*77c1e3ccSAndroid Build Coastguard Worker int aom_noise_strength_solver_fit_piecewise(
118*77c1e3ccSAndroid Build Coastguard Worker     const aom_noise_strength_solver_t *solver, int max_num_points,
119*77c1e3ccSAndroid Build Coastguard Worker     aom_noise_strength_lut_t *lut);
120*77c1e3ccSAndroid Build Coastguard Worker 
121*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Helper for holding precomputed data for finding flat blocks.
122*77c1e3ccSAndroid Build Coastguard Worker  *
123*77c1e3ccSAndroid Build Coastguard Worker  * Internally a block is modeled with a low-order polynomial model. A
124*77c1e3ccSAndroid Build Coastguard Worker  * planar model would be a bunch of equations like:
125*77c1e3ccSAndroid Build Coastguard Worker  * <[y_i x_i 1], [a_1, a_2, a_3]>  = b_i
126*77c1e3ccSAndroid Build Coastguard Worker  * for each point in the block. The system matrix A with row i as [y_i x_i 1]
127*77c1e3ccSAndroid Build Coastguard Worker  * is maintained as is the inverse, inv(A'*A), so that the plane parameters
128*77c1e3ccSAndroid Build Coastguard Worker  * can be fit for each block.
129*77c1e3ccSAndroid Build Coastguard Worker  */
130*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
131*77c1e3ccSAndroid Build Coastguard Worker   double *AtA_inv;
132*77c1e3ccSAndroid Build Coastguard Worker   double *A;
133*77c1e3ccSAndroid Build Coastguard Worker   int num_params;  // The number of parameters used for internal low-order model
134*77c1e3ccSAndroid Build Coastguard Worker   int block_size;  // The block size the finder was initialized with
135*77c1e3ccSAndroid Build Coastguard Worker   double normalization;  // Normalization factor (1 / (2^(bit_depth) - 1))
136*77c1e3ccSAndroid Build Coastguard Worker   int use_highbd;        // Whether input data should be interpreted as uint16
137*77c1e3ccSAndroid Build Coastguard Worker } aom_flat_block_finder_t;
138*77c1e3ccSAndroid Build Coastguard Worker 
139*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Init the block_finder with the given block size, bit_depth */
140*77c1e3ccSAndroid Build Coastguard Worker int aom_flat_block_finder_init(aom_flat_block_finder_t *block_finder,
141*77c1e3ccSAndroid Build Coastguard Worker                                int block_size, int bit_depth, int use_highbd);
142*77c1e3ccSAndroid Build Coastguard Worker void aom_flat_block_finder_free(aom_flat_block_finder_t *block_finder);
143*77c1e3ccSAndroid Build Coastguard Worker 
144*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Helper to extract a block and low order "planar" model. */
145*77c1e3ccSAndroid Build Coastguard Worker void aom_flat_block_finder_extract_block(
146*77c1e3ccSAndroid Build Coastguard Worker     const aom_flat_block_finder_t *block_finder, const uint8_t *const data,
147*77c1e3ccSAndroid Build Coastguard Worker     int w, int h, int stride, int offsx, int offsy, double *plane,
148*77c1e3ccSAndroid Build Coastguard Worker     double *block);
149*77c1e3ccSAndroid Build Coastguard Worker 
150*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Runs the flat block finder on the input data.
151*77c1e3ccSAndroid Build Coastguard Worker  *
152*77c1e3ccSAndroid Build Coastguard Worker  * Find flat blocks in the input image data. Returns a map of
153*77c1e3ccSAndroid Build Coastguard Worker  * flat_blocks, where the value of flat_blocks map will be non-zero
154*77c1e3ccSAndroid Build Coastguard Worker  * when a block is determined to be flat. A higher value indicates a bigger
155*77c1e3ccSAndroid Build Coastguard Worker  * confidence in the decision.
156*77c1e3ccSAndroid Build Coastguard Worker  */
157*77c1e3ccSAndroid Build Coastguard Worker int aom_flat_block_finder_run(const aom_flat_block_finder_t *block_finder,
158*77c1e3ccSAndroid Build Coastguard Worker                               const uint8_t *const data, int w, int h,
159*77c1e3ccSAndroid Build Coastguard Worker                               int stride, uint8_t *flat_blocks);
160*77c1e3ccSAndroid Build Coastguard Worker 
161*77c1e3ccSAndroid Build Coastguard Worker // The noise shape indicates the allowed coefficients in the AR model.
162*77c1e3ccSAndroid Build Coastguard Worker enum {
163*77c1e3ccSAndroid Build Coastguard Worker   AOM_NOISE_SHAPE_DIAMOND = 0,
164*77c1e3ccSAndroid Build Coastguard Worker   AOM_NOISE_SHAPE_SQUARE = 1
165*77c1e3ccSAndroid Build Coastguard Worker } UENUM1BYTE(aom_noise_shape);
166*77c1e3ccSAndroid Build Coastguard Worker 
167*77c1e3ccSAndroid Build Coastguard Worker // The parameters of the noise model include the shape type, lag, the
168*77c1e3ccSAndroid Build Coastguard Worker // bit depth of the input images provided, and whether the input images
169*77c1e3ccSAndroid Build Coastguard Worker // will be using uint16 (or uint8) representation.
170*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
171*77c1e3ccSAndroid Build Coastguard Worker   aom_noise_shape shape;
172*77c1e3ccSAndroid Build Coastguard Worker   int lag;
173*77c1e3ccSAndroid Build Coastguard Worker   int bit_depth;
174*77c1e3ccSAndroid Build Coastguard Worker   int use_highbd;
175*77c1e3ccSAndroid Build Coastguard Worker } aom_noise_model_params_t;
176*77c1e3ccSAndroid Build Coastguard Worker 
177*77c1e3ccSAndroid Build Coastguard Worker /*!\brief State of a noise model estimate for a single channel.
178*77c1e3ccSAndroid Build Coastguard Worker  *
179*77c1e3ccSAndroid Build Coastguard Worker  * This contains a system of equations that can be used to solve
180*77c1e3ccSAndroid Build Coastguard Worker  * for the auto-regressive coefficients as well as a noise strength
181*77c1e3ccSAndroid Build Coastguard Worker  * solver that can be used to model noise strength as a function of
182*77c1e3ccSAndroid Build Coastguard Worker  * intensity.
183*77c1e3ccSAndroid Build Coastguard Worker  */
184*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
185*77c1e3ccSAndroid Build Coastguard Worker   aom_equation_system_t eqns;
186*77c1e3ccSAndroid Build Coastguard Worker   aom_noise_strength_solver_t strength_solver;
187*77c1e3ccSAndroid Build Coastguard Worker   int num_observations;  // The number of observations in the eqn system
188*77c1e3ccSAndroid Build Coastguard Worker   double ar_gain;        // The gain of the current AR filter
189*77c1e3ccSAndroid Build Coastguard Worker } aom_noise_state_t;
190*77c1e3ccSAndroid Build Coastguard Worker 
191*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Complete model of noise for a planar video
192*77c1e3ccSAndroid Build Coastguard Worker  *
193*77c1e3ccSAndroid Build Coastguard Worker  * This includes a noise model for the latest frame and an aggregated
194*77c1e3ccSAndroid Build Coastguard Worker  * estimate over all previous frames that had similar parameters.
195*77c1e3ccSAndroid Build Coastguard Worker  */
196*77c1e3ccSAndroid Build Coastguard Worker typedef struct {
197*77c1e3ccSAndroid Build Coastguard Worker   aom_noise_model_params_t params;
198*77c1e3ccSAndroid Build Coastguard Worker   aom_noise_state_t combined_state[3];  // Combined state per channel
199*77c1e3ccSAndroid Build Coastguard Worker   aom_noise_state_t latest_state[3];    // Latest state per channel
200*77c1e3ccSAndroid Build Coastguard Worker   int (*coords)[2];  // Offsets (x,y) of the coefficient samples
201*77c1e3ccSAndroid Build Coastguard Worker   int n;             // Number of parameters (size of coords)
202*77c1e3ccSAndroid Build Coastguard Worker   int bit_depth;
203*77c1e3ccSAndroid Build Coastguard Worker } aom_noise_model_t;
204*77c1e3ccSAndroid Build Coastguard Worker 
205*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Result of a noise model update. */
206*77c1e3ccSAndroid Build Coastguard Worker enum {
207*77c1e3ccSAndroid Build Coastguard Worker   AOM_NOISE_STATUS_OK = 0,
208*77c1e3ccSAndroid Build Coastguard Worker   AOM_NOISE_STATUS_INVALID_ARGUMENT,
209*77c1e3ccSAndroid Build Coastguard Worker   AOM_NOISE_STATUS_INSUFFICIENT_FLAT_BLOCKS,
210*77c1e3ccSAndroid Build Coastguard Worker   AOM_NOISE_STATUS_DIFFERENT_NOISE_TYPE,
211*77c1e3ccSAndroid Build Coastguard Worker   AOM_NOISE_STATUS_INTERNAL_ERROR,
212*77c1e3ccSAndroid Build Coastguard Worker } UENUM1BYTE(aom_noise_status_t);
213*77c1e3ccSAndroid Build Coastguard Worker 
214*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Initializes a noise model with the given parameters.
215*77c1e3ccSAndroid Build Coastguard Worker  *
216*77c1e3ccSAndroid Build Coastguard Worker  * Returns 0 on failure.
217*77c1e3ccSAndroid Build Coastguard Worker  */
218*77c1e3ccSAndroid Build Coastguard Worker int aom_noise_model_init(aom_noise_model_t *model,
219*77c1e3ccSAndroid Build Coastguard Worker                          const aom_noise_model_params_t params);
220*77c1e3ccSAndroid Build Coastguard Worker void aom_noise_model_free(aom_noise_model_t *model);
221*77c1e3ccSAndroid Build Coastguard Worker 
222*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Updates the noise model with a new frame observation.
223*77c1e3ccSAndroid Build Coastguard Worker  *
224*77c1e3ccSAndroid Build Coastguard Worker  * Updates the noise model with measurements from the given input frame and a
225*77c1e3ccSAndroid Build Coastguard Worker  * denoised variant of it. Noise is sampled from flat blocks using the flat
226*77c1e3ccSAndroid Build Coastguard Worker  * block map.
227*77c1e3ccSAndroid Build Coastguard Worker  *
228*77c1e3ccSAndroid Build Coastguard Worker  * Returns a noise_status indicating if the update was successful. If the
229*77c1e3ccSAndroid Build Coastguard Worker  * Update was successful, the combined_state is updated with measurements from
230*77c1e3ccSAndroid Build Coastguard Worker  * the provided frame. If status is OK or DIFFERENT_NOISE_TYPE, the latest noise
231*77c1e3ccSAndroid Build Coastguard Worker  * state will be updated with measurements from the provided frame.
232*77c1e3ccSAndroid Build Coastguard Worker  *
233*77c1e3ccSAndroid Build Coastguard Worker  * \param[in,out] noise_model     The noise model to be updated
234*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     data            Raw frame data
235*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     denoised        Denoised frame data.
236*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     w               Frame width
237*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     h               Frame height
238*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     strides         Stride of the planes
239*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     chroma_sub_log2 Chroma subsampling for planes != 0.
240*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     flat_blocks     A map to blocks that have been determined flat
241*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     block_size      The size of blocks.
242*77c1e3ccSAndroid Build Coastguard Worker  */
243*77c1e3ccSAndroid Build Coastguard Worker aom_noise_status_t aom_noise_model_update(
244*77c1e3ccSAndroid Build Coastguard Worker     aom_noise_model_t *const noise_model, const uint8_t *const data[3],
245*77c1e3ccSAndroid Build Coastguard Worker     const uint8_t *const denoised[3], int w, int h, int strides[3],
246*77c1e3ccSAndroid Build Coastguard Worker     int chroma_sub_log2[2], const uint8_t *const flat_blocks, int block_size);
247*77c1e3ccSAndroid Build Coastguard Worker 
248*77c1e3ccSAndroid Build Coastguard Worker /*\brief Save the "latest" estimate into the "combined" estimate.
249*77c1e3ccSAndroid Build Coastguard Worker  *
250*77c1e3ccSAndroid Build Coastguard Worker  * This is meant to be called when the noise modeling detected a change
251*77c1e3ccSAndroid Build Coastguard Worker  * in parameters (or for example, if a user wanted to reset estimation at
252*77c1e3ccSAndroid Build Coastguard Worker  * a shot boundary).
253*77c1e3ccSAndroid Build Coastguard Worker  */
254*77c1e3ccSAndroid Build Coastguard Worker void aom_noise_model_save_latest(aom_noise_model_t *noise_model);
255*77c1e3ccSAndroid Build Coastguard Worker 
256*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Converts the noise_model parameters to the corresponding
257*77c1e3ccSAndroid Build Coastguard Worker  *    grain_parameters.
258*77c1e3ccSAndroid Build Coastguard Worker  *
259*77c1e3ccSAndroid Build Coastguard Worker  * The noise structs in this file are suitable for estimation (e.g., using
260*77c1e3ccSAndroid Build Coastguard Worker  * floats), but the grain parameters in the bitstream are quantized. This
261*77c1e3ccSAndroid Build Coastguard Worker  * function does the conversion by selecting the correct quantization levels.
262*77c1e3ccSAndroid Build Coastguard Worker  */
263*77c1e3ccSAndroid Build Coastguard Worker int aom_noise_model_get_grain_parameters(aom_noise_model_t *const noise_model,
264*77c1e3ccSAndroid Build Coastguard Worker                                          aom_film_grain_t *film_grain);
265*77c1e3ccSAndroid Build Coastguard Worker 
266*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Perform a Wiener filter denoising in 2D using the provided noise psd.
267*77c1e3ccSAndroid Build Coastguard Worker  *
268*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     data            Raw frame data
269*77c1e3ccSAndroid Build Coastguard Worker  * \param[out]    denoised        Denoised frame data
270*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     w               Frame width
271*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     h               Frame height
272*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     stride          Stride of the planes
273*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     chroma_sub_log2 Chroma subsampling for planes != 0.
274*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     noise_psd       The power spectral density of the noise
275*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     block_size      The size of blocks
276*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     bit_depth       Bit depth of the image
277*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     use_highbd      If true, uint8 pointers are interpreted as
278*77c1e3ccSAndroid Build Coastguard Worker  *                                uint16 and stride is measured in uint16.
279*77c1e3ccSAndroid Build Coastguard Worker  *                                This must be true when bit_depth >= 10.
280*77c1e3ccSAndroid Build Coastguard Worker  */
281*77c1e3ccSAndroid Build Coastguard Worker int aom_wiener_denoise_2d(const uint8_t *const data[3], uint8_t *denoised[3],
282*77c1e3ccSAndroid Build Coastguard Worker                           int w, int h, int stride[3], int chroma_sub_log2[2],
283*77c1e3ccSAndroid Build Coastguard Worker                           float *noise_psd[3], int block_size, int bit_depth,
284*77c1e3ccSAndroid Build Coastguard Worker                           int use_highbd);
285*77c1e3ccSAndroid Build Coastguard Worker 
286*77c1e3ccSAndroid Build Coastguard Worker struct aom_denoise_and_model_t;
287*77c1e3ccSAndroid Build Coastguard Worker 
288*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Denoise the buffer and model the residual noise.
289*77c1e3ccSAndroid Build Coastguard Worker  *
290*77c1e3ccSAndroid Build Coastguard Worker  * This is meant to be called sequentially on input frames. The input buffer
291*77c1e3ccSAndroid Build Coastguard Worker  * is denoised and the residual noise is modelled. The current noise estimate
292*77c1e3ccSAndroid Build Coastguard Worker  * is populated in film_grain. Returns true on success. The grain.apply_grain
293*77c1e3ccSAndroid Build Coastguard Worker  * parameter will be true when the input buffer was successfully denoised and
294*77c1e3ccSAndroid Build Coastguard Worker  * grain was modelled. Returns false on error.
295*77c1e3ccSAndroid Build Coastguard Worker  *
296*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     ctx           Struct allocated with
297*77c1e3ccSAndroid Build Coastguard Worker  *                              aom_denoise_and_model_alloc that holds some
298*77c1e3ccSAndroid Build Coastguard Worker  *                              buffers for denoising and the current noise
299*77c1e3ccSAndroid Build Coastguard Worker  *                              estimate.
300*77c1e3ccSAndroid Build Coastguard Worker  * \param[in,out] sd            The raw input buffer to be denoised.
301*77c1e3ccSAndroid Build Coastguard Worker  * \param[out]    grain         Output film grain parameters
302*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]     apply_denoise Whether or not to apply the denoising to the
303*77c1e3ccSAndroid Build Coastguard Worker  *                              frame that will be encoded
304*77c1e3ccSAndroid Build Coastguard Worker  */
305*77c1e3ccSAndroid Build Coastguard Worker int aom_denoise_and_model_run(struct aom_denoise_and_model_t *ctx,
306*77c1e3ccSAndroid Build Coastguard Worker                               const YV12_BUFFER_CONFIG *sd,
307*77c1e3ccSAndroid Build Coastguard Worker                               aom_film_grain_t *grain, int apply_denoise);
308*77c1e3ccSAndroid Build Coastguard Worker 
309*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Allocates a context that can be used for denoising and noise modeling.
310*77c1e3ccSAndroid Build Coastguard Worker  *
311*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  bit_depth   Bit depth of buffers this will be run on.
312*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  block_size  Block size for noise modeling and flat block
313*77c1e3ccSAndroid Build Coastguard Worker  *                         estimation
314*77c1e3ccSAndroid Build Coastguard Worker  * \param[in]  noise_level The noise_level (2.5 for moderate noise, and 5 for
315*77c1e3ccSAndroid Build Coastguard Worker  *                         higher levels of noise)
316*77c1e3ccSAndroid Build Coastguard Worker  */
317*77c1e3ccSAndroid Build Coastguard Worker struct aom_denoise_and_model_t *aom_denoise_and_model_alloc(int bit_depth,
318*77c1e3ccSAndroid Build Coastguard Worker                                                             int block_size,
319*77c1e3ccSAndroid Build Coastguard Worker                                                             float noise_level);
320*77c1e3ccSAndroid Build Coastguard Worker 
321*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Frees the denoise context allocated with aom_denoise_and_model_alloc
322*77c1e3ccSAndroid Build Coastguard Worker  */
323*77c1e3ccSAndroid Build Coastguard Worker void aom_denoise_and_model_free(struct aom_denoise_and_model_t *denoise_model);
324*77c1e3ccSAndroid Build Coastguard Worker 
325*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus
326*77c1e3ccSAndroid Build Coastguard Worker }  // extern "C"
327*77c1e3ccSAndroid Build Coastguard Worker #endif  // __cplusplus
328*77c1e3ccSAndroid Build Coastguard Worker #endif  // AOM_AOM_DSP_NOISE_MODEL_H_
329