/src/avm/av2/common/intra_dip.cc
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2023, 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 | | #include <cstdio> |
13 | | #include <memory> |
14 | | |
15 | | #include "avm_dsp/avm_dsp_common.h" |
16 | | #include "av2/common/av2_common_int.h" |
17 | | |
18 | | extern "C" { |
19 | | #include "av2/common/intra_matrix.h" |
20 | | } |
21 | | |
22 | | #include "av2/common/intra_dip.h" |
23 | | |
24 | | #define INPUT_FEATURES 11 |
25 | | |
26 | | // Resample output from DIP prediction (8x8) to the actual transform |
27 | | // block size. This is some by upsampling if dimension is > 8, or |
28 | | // downsampling/decimation if dimension is < 8. Resampling is done |
29 | | // in the horizontal dimension first followed by vertical. |
30 | | void resample_output_c(uint16_t *dst, int dst_stride, const uint16_t *above_row, |
31 | | const uint16_t *left_col, uint16_t *ml_output, |
32 | 0 | int bw_log2, int bh_log2, int transpose) { |
33 | | // up/down sampling factors |
34 | 0 | int pred_x = 8; |
35 | 0 | int pred_y = 8; |
36 | 0 | int upx_log2 = bw_log2 - 3; |
37 | 0 | int upy_log2 = bh_log2 - 3; |
38 | 0 | int downx_log2 = 0; |
39 | 0 | int downy_log2 = 0; |
40 | 0 | if (upx_log2 < 0) { |
41 | 0 | downx_log2 = -upx_log2; |
42 | 0 | upx_log2 = 0; |
43 | 0 | } |
44 | 0 | if (upy_log2 < 0) { |
45 | 0 | downy_log2 = -upy_log2; |
46 | 0 | upy_log2 = 0; |
47 | 0 | } |
48 | 0 | int mx = 1 << upx_log2; |
49 | 0 | int my = 1 << upy_log2; |
50 | 0 | int downx = 1 << downx_log2; |
51 | 0 | int downy = 1 << downy_log2; |
52 | 0 | int bw = 1 << bw_log2; |
53 | | // Copy ml_output[] into dst[] |
54 | 0 | for (int i = 0; i < pred_y >> downy_log2; i++) { |
55 | 0 | for (int j = 0; j < pred_x >> downx_log2; j++) { |
56 | 0 | int x = j * mx + (mx - 1); |
57 | 0 | int y = i * my + (my - 1); |
58 | 0 | int i1 = i * downy; |
59 | 0 | int j1 = j * downx; |
60 | 0 | int ii = transpose ? j1 : i1; |
61 | 0 | int jj = transpose ? i1 : j1; |
62 | 0 | dst[y * dst_stride + x] = ml_output[ii * pred_x + jj]; |
63 | 0 | } |
64 | 0 | } |
65 | | // Interpolate horizontally. |
66 | 0 | for (int i = 0; i < pred_y >> downy_log2; i++) { |
67 | 0 | int y = i * my + (my - 1); |
68 | 0 | int p0 = 0; |
69 | 0 | int p1 = left_col[y]; |
70 | 0 | for (int j = 0; j < pred_x >> downx_log2; j++) { |
71 | 0 | int x = j * mx; |
72 | 0 | p0 = p1; |
73 | 0 | p1 = dst[y * dst_stride + x + mx - 1]; |
74 | 0 | for (int k = 0; k < mx - 1; k++) { |
75 | 0 | int k1 = k + 1; |
76 | 0 | dst[y * dst_stride + x + k] = (p0 * (mx - k1) + (p1 * k1)) >> upx_log2; |
77 | 0 | } |
78 | 0 | } |
79 | 0 | } |
80 | | // Interpolate vertically. |
81 | 0 | for (int x = 0; x < bw; x++) { |
82 | 0 | int p0 = 0; |
83 | 0 | int p1 = above_row[x]; |
84 | 0 | for (int i = 0; i < pred_y >> downy_log2; i++) { |
85 | 0 | int y = i * my; |
86 | 0 | p0 = p1; |
87 | 0 | p1 = dst[(y + my - 1) * dst_stride + x]; |
88 | 0 | for (int k = 0; k < my - 1; k++) { |
89 | 0 | int k1 = k + 1; |
90 | 0 | dst[(y + k) * dst_stride + x] = |
91 | 0 | (p0 * (my - k1) + (p1 * k1)) >> upy_log2; |
92 | 0 | } |
93 | 0 | } |
94 | 0 | } |
95 | 0 | } |
96 | | |
97 | | // Create intra DIP prediction for large blocks |
98 | | extern "C" void av2_highbd_intra_dip_predictor(int mode, uint16_t *dst, |
99 | | int dst_stride, |
100 | | const uint16_t *above_row, |
101 | | const uint16_t *left_col, |
102 | | TX_SIZE tx_size, int bd |
103 | | #if CONFIG_DIP_EXT_PRUNING |
104 | | , |
105 | | uint16_t *intra_dip_features |
106 | | #endif // CONFIG_DIP_EXT_PRUNING |
107 | 61.2k | ) { |
108 | 61.2k | uint16_t ml_input[INPUT_FEATURES]; |
109 | 61.2k | uint16_t ml_output[64]; |
110 | 61.2k | const int bw_log2 = tx_size_wide_log2[tx_size]; |
111 | 61.2k | const int bh_log2 = tx_size_high_log2[tx_size]; |
112 | 61.2k | int transpose = mode >> 4; |
113 | 61.2k | int iml_mode = mode & 15; |
114 | 61.2k | int down_x_log2 = bw_log2 - 2; |
115 | 61.2k | int down_y_log2 = bh_log2 - 2; |
116 | 61.2k | const int down0_log2 = transpose ? down_y_log2 : down_x_log2; |
117 | 61.2k | const int down1_log2 = transpose ? down_x_log2 : down_y_log2; |
118 | 61.2k | const int down0 = 1 << down0_log2; |
119 | 61.2k | const int down1 = 1 << down1_log2; |
120 | 61.2k | int rnd0 = down0 >> 1; |
121 | 61.2k | int rnd1 = down1 >> 1; |
122 | 61.2k | const uint16_t *edge0 = transpose ? left_col : above_row; |
123 | 61.2k | const uint16_t *edge1 = transpose ? above_row : left_col; |
124 | | |
125 | 61.2k | int ml_i = 0; |
126 | | // Corner |
127 | 61.2k | ml_input[ml_i++] = edge0[-1]; |
128 | | |
129 | | // Calc above input |
130 | 306k | for (int i = 0; i < 4; i++) { |
131 | 244k | int sum = 0; |
132 | 1.10M | for (int j = 0; j < down0; j++) { |
133 | 863k | sum += *edge0++; |
134 | 863k | } |
135 | 244k | ml_input[ml_i++] = (sum + rnd0) >> down0_log2; |
136 | 244k | } |
137 | | |
138 | | // Calc left input |
139 | 306k | for (int i = 0; i < 4; i++) { |
140 | 244k | int sum = 0; |
141 | 1.09M | for (int j = 0; j < down1; j++) { |
142 | 850k | sum += *edge1++; |
143 | 850k | } |
144 | 244k | ml_input[ml_i++] = (sum + rnd1) >> down1_log2; |
145 | 244k | } |
146 | | |
147 | 61.2k | int n_overhang = 1; |
148 | | // Calc above_left input |
149 | 122k | for (int i = 0; i < n_overhang; i++) { |
150 | 61.2k | int sum = 0; |
151 | 277k | for (int j = 0; j < down0; j++) { |
152 | 215k | sum += *edge0++; |
153 | 215k | } |
154 | 61.2k | ml_input[ml_i++] = (sum + rnd0) >> down0_log2; |
155 | 61.2k | } |
156 | | |
157 | | // Calc bottom_left input |
158 | 122k | for (int i = 0; i < n_overhang; i++) { |
159 | 61.2k | int sum = 0; |
160 | 273k | for (int j = 0; j < down1; j++) { |
161 | 212k | sum += *edge1++; |
162 | 212k | } |
163 | 61.2k | ml_input[ml_i++] = (sum + rnd1) >> down1_log2; |
164 | 61.2k | } |
165 | | |
166 | 61.2k | av2_intra_matrix_pred(ml_input, iml_mode, ml_output, bd); |
167 | | |
168 | 61.2k | #if CONFIG_DIP_EXT_PRUNING |
169 | | // Collect DIP input features for ML pruning. |
170 | 61.2k | if (mode == 0) { |
171 | 48.6k | for (int i = 0; i < 11; i++) { |
172 | 44.6k | intra_dip_features[i] = ml_input[i]; |
173 | 44.6k | } |
174 | 4.05k | } |
175 | 61.2k | #endif // CONFIG_DIP_EXT_PRUNING |
176 | 61.2k | resample_output(dst, dst_stride, above_row, left_col, ml_output, bw_log2, |
177 | 61.2k | bh_log2, transpose); |
178 | 61.2k | } |