1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2016, 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 #ifndef AOM_AV1_ENCODER_PICKRST_H_
12*77c1e3ccSAndroid Build Coastguard Worker #define AOM_AV1_ENCODER_PICKRST_H_
13*77c1e3ccSAndroid Build Coastguard Worker
14*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus
15*77c1e3ccSAndroid Build Coastguard Worker extern "C" {
16*77c1e3ccSAndroid Build Coastguard Worker #endif
17*77c1e3ccSAndroid Build Coastguard Worker
18*77c1e3ccSAndroid Build Coastguard Worker #include "av1/encoder/encoder.h"
19*77c1e3ccSAndroid Build Coastguard Worker
20*77c1e3ccSAndroid Build Coastguard Worker struct yv12_buffer_config;
21*77c1e3ccSAndroid Build Coastguard Worker struct AV1_COMP;
22*77c1e3ccSAndroid Build Coastguard Worker
23*77c1e3ccSAndroid Build Coastguard Worker // Enable extra debugging for loop restoration costing?
24*77c1e3ccSAndroid Build Coastguard Worker //
25*77c1e3ccSAndroid Build Coastguard Worker // If this is set to 1, then we record not just the selected LR parameters, but
26*77c1e3ccSAndroid Build Coastguard Worker // also the values which the search process thinks they should be delta-coded
27*77c1e3ccSAndroid Build Coastguard Worker // against. Then, when writing out the bitstream, we verify this information,
28*77c1e3ccSAndroid Build Coastguard Worker // to help ensure that the search code is costing things properly
29*77c1e3ccSAndroid Build Coastguard Worker #define DEBUG_LR_COSTING 0
30*77c1e3ccSAndroid Build Coastguard Worker
31*77c1e3ccSAndroid Build Coastguard Worker #if DEBUG_LR_COSTING
32*77c1e3ccSAndroid Build Coastguard Worker #define MAX_LR_UNITS_W 64
33*77c1e3ccSAndroid Build Coastguard Worker #define MAX_LR_UNITS_H 64
34*77c1e3ccSAndroid Build Coastguard Worker
35*77c1e3ccSAndroid Build Coastguard Worker // Storage for reference parameters.
36*77c1e3ccSAndroid Build Coastguard Worker //
37*77c1e3ccSAndroid Build Coastguard Worker // The storage size is determined by:
38*77c1e3ccSAndroid Build Coastguard Worker // * This is always written and then checked within the same frame encode pass,
39*77c1e3ccSAndroid Build Coastguard Worker // so we do not need to buffer multiple frames of data
40*77c1e3ccSAndroid Build Coastguard Worker // * The parameters can be different per plane within one frame
41*77c1e3ccSAndroid Build Coastguard Worker // * The relevant set of ref parameters can differ between the search where
42*77c1e3ccSAndroid Build Coastguard Worker // we set the frame restoration mode to RESTORE_WIENER, and the search where
43*77c1e3ccSAndroid Build Coastguard Worker // we set it to RESTORE_SWITCHABLE.
44*77c1e3ccSAndroid Build Coastguard Worker // So we need to store at least two sets of Wiener params and two sets of
45*77c1e3ccSAndroid Build Coastguard Worker // SGR params, and the easiest way to do this is to index by
46*77c1e3ccSAndroid Build Coastguard Worker // frame_restoration_type
47*77c1e3ccSAndroid Build Coastguard Worker extern RestorationUnitInfo lr_ref_params[RESTORE_TYPES][MAX_MB_PLANE]
48*77c1e3ccSAndroid Build Coastguard Worker [MAX_LR_UNITS_W * MAX_LR_UNITS_H];
49*77c1e3ccSAndroid Build Coastguard Worker #endif // DEBUG_LR_COSTING
50*77c1e3ccSAndroid Build Coastguard Worker
51*77c1e3ccSAndroid Build Coastguard Worker static const uint8_t g_shuffle_stats_data[16] = {
52*77c1e3ccSAndroid Build Coastguard Worker 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
53*77c1e3ccSAndroid Build Coastguard Worker };
54*77c1e3ccSAndroid Build Coastguard Worker
55*77c1e3ccSAndroid Build Coastguard Worker static const uint8_t g_shuffle_stats_highbd_data[32] = {
56*77c1e3ccSAndroid Build Coastguard Worker 0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9,
57*77c1e3ccSAndroid Build Coastguard Worker 0, 1, 2, 3, 2, 3, 4, 5, 4, 5, 6, 7, 6, 7, 8, 9,
58*77c1e3ccSAndroid Build Coastguard Worker };
59*77c1e3ccSAndroid Build Coastguard Worker
find_average(const uint8_t * src,int h_start,int h_end,int v_start,int v_end,int stride)60*77c1e3ccSAndroid Build Coastguard Worker static inline uint8_t find_average(const uint8_t *src, int h_start, int h_end,
61*77c1e3ccSAndroid Build Coastguard Worker int v_start, int v_end, int stride) {
62*77c1e3ccSAndroid Build Coastguard Worker uint64_t sum = 0;
63*77c1e3ccSAndroid Build Coastguard Worker for (int i = v_start; i < v_end; i++) {
64*77c1e3ccSAndroid Build Coastguard Worker for (int j = h_start; j < h_end; j++) {
65*77c1e3ccSAndroid Build Coastguard Worker sum += src[i * stride + j];
66*77c1e3ccSAndroid Build Coastguard Worker }
67*77c1e3ccSAndroid Build Coastguard Worker }
68*77c1e3ccSAndroid Build Coastguard Worker uint64_t avg = sum / ((v_end - v_start) * (h_end - h_start));
69*77c1e3ccSAndroid Build Coastguard Worker return (uint8_t)avg;
70*77c1e3ccSAndroid Build Coastguard Worker }
71*77c1e3ccSAndroid Build Coastguard Worker
72*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_AV1_HIGHBITDEPTH
find_average_highbd(const uint16_t * src,int h_start,int h_end,int v_start,int v_end,int stride)73*77c1e3ccSAndroid Build Coastguard Worker static inline uint16_t find_average_highbd(const uint16_t *src, int h_start,
74*77c1e3ccSAndroid Build Coastguard Worker int h_end, int v_start, int v_end,
75*77c1e3ccSAndroid Build Coastguard Worker int stride) {
76*77c1e3ccSAndroid Build Coastguard Worker uint64_t sum = 0;
77*77c1e3ccSAndroid Build Coastguard Worker for (int i = v_start; i < v_end; i++) {
78*77c1e3ccSAndroid Build Coastguard Worker for (int j = h_start; j < h_end; j++) {
79*77c1e3ccSAndroid Build Coastguard Worker sum += src[i * stride + j];
80*77c1e3ccSAndroid Build Coastguard Worker }
81*77c1e3ccSAndroid Build Coastguard Worker }
82*77c1e3ccSAndroid Build Coastguard Worker uint64_t avg = sum / ((v_end - v_start) * (h_end - h_start));
83*77c1e3ccSAndroid Build Coastguard Worker return (uint16_t)avg;
84*77c1e3ccSAndroid Build Coastguard Worker }
85*77c1e3ccSAndroid Build Coastguard Worker #endif
86*77c1e3ccSAndroid Build Coastguard Worker
87*77c1e3ccSAndroid Build Coastguard Worker /*!\brief Algorithm for AV1 loop restoration search and estimation.
88*77c1e3ccSAndroid Build Coastguard Worker *
89*77c1e3ccSAndroid Build Coastguard Worker * \ingroup in_loop_restoration
90*77c1e3ccSAndroid Build Coastguard Worker * This function determines proper restoration filter types and
91*77c1e3ccSAndroid Build Coastguard Worker * associated parameters for each restoration unit in a frame.
92*77c1e3ccSAndroid Build Coastguard Worker *
93*77c1e3ccSAndroid Build Coastguard Worker * \param[in] sd Source frame buffer
94*77c1e3ccSAndroid Build Coastguard Worker * \param[in,out] cpi Top-level encoder structure
95*77c1e3ccSAndroid Build Coastguard Worker *
96*77c1e3ccSAndroid Build Coastguard Worker * \remark Nothing is returned. Instead, chosen restoration filter
97*77c1e3ccSAndroid Build Coastguard Worker * types and parameters are stored per plane in the \c rst_info structure
98*77c1e3ccSAndroid Build Coastguard Worker * of type \ref RestorationInfo inside \c cpi->common:
99*77c1e3ccSAndroid Build Coastguard Worker * \arg \c rst_info[ \c 0 ]: Chosen parameters for Y plane
100*77c1e3ccSAndroid Build Coastguard Worker * \arg \c rst_info[ \c 1 ]: Chosen parameters for U plane if it exists
101*77c1e3ccSAndroid Build Coastguard Worker * \arg \c rst_info[ \c 2 ]: Chosen parameters for V plane if it exists
102*77c1e3ccSAndroid Build Coastguard Worker * \par
103*77c1e3ccSAndroid Build Coastguard Worker * The following fields in each \c rst_info[ \c p], \c p = 0, 1, 2
104*77c1e3ccSAndroid Build Coastguard Worker * are populated:
105*77c1e3ccSAndroid Build Coastguard Worker * \arg \c rst_info[ \c p ].\c frame_restoration_type
106*77c1e3ccSAndroid Build Coastguard Worker * \arg \c rst_info[ \c p ].\c unit_info[ \c u ],
107*77c1e3ccSAndroid Build Coastguard Worker * for each \c u in 0, 1, ..., \c n( \c p ) - 1,
108*77c1e3ccSAndroid Build Coastguard Worker * where \c n( \c p ) is the number of restoration units in plane \c p.
109*77c1e3ccSAndroid Build Coastguard Worker * \par
110*77c1e3ccSAndroid Build Coastguard Worker * The following fields in each \c rst_info[ \c p ].\c unit_info[ \c u ],
111*77c1e3ccSAndroid Build Coastguard Worker * \c p = 0, 1, 2 and \c u = 0, 1, ..., \c n( \c p ) - 1, of type
112*77c1e3ccSAndroid Build Coastguard Worker * \ref RestorationUnitInfo are populated:
113*77c1e3ccSAndroid Build Coastguard Worker * \arg \c rst_info[ \c p ].\c unit_info[ \c u ].\c restoration_type
114*77c1e3ccSAndroid Build Coastguard Worker * \arg \c rst_info[ \c p ].\c unit_info[ \c u ].\c wiener_info OR
115*77c1e3ccSAndroid Build Coastguard Worker * \c rst_info[ \c p ].\c unit_info[ \c u ].\c sgrproj_info OR
116*77c1e3ccSAndroid Build Coastguard Worker * neither, depending on
117*77c1e3ccSAndroid Build Coastguard Worker * \c rst_info[ \c p ].\c unit_info[ \c u ].\c restoration_type
118*77c1e3ccSAndroid Build Coastguard Worker *
119*77c1e3ccSAndroid Build Coastguard Worker */
120*77c1e3ccSAndroid Build Coastguard Worker void av1_pick_filter_restoration(const YV12_BUFFER_CONFIG *sd, AV1_COMP *cpi);
121*77c1e3ccSAndroid Build Coastguard Worker
122*77c1e3ccSAndroid Build Coastguard Worker #ifdef __cplusplus
123*77c1e3ccSAndroid Build Coastguard Worker } // extern "C"
124*77c1e3ccSAndroid Build Coastguard Worker #endif
125*77c1e3ccSAndroid Build Coastguard Worker
126*77c1e3ccSAndroid Build Coastguard Worker #endif // AOM_AV1_ENCODER_PICKRST_H_
127