• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The libgav1 Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/dsp/weight_mask.h"
16 
17 #include <algorithm>
18 #include <cassert>
19 #include <cstddef>
20 #include <cstdint>
21 #include <string>
22 #include <type_traits>
23 
24 #include "src/dsp/dsp.h"
25 #include "src/utils/common.h"
26 
27 namespace libgav1 {
28 namespace dsp {
29 namespace {
30 
31 template <int width, int height, int bitdepth, bool mask_is_inverse>
WeightMask_C(const void * prediction_0,const void * prediction_1,uint8_t * mask,ptrdiff_t mask_stride)32 void WeightMask_C(const void* prediction_0, const void* prediction_1,
33                   uint8_t* mask, ptrdiff_t mask_stride) {
34   using PredType =
35       typename std::conditional<bitdepth == 8, int16_t, uint16_t>::type;
36   const auto* pred_0 = static_cast<const PredType*>(prediction_0);
37   const auto* pred_1 = static_cast<const PredType*>(prediction_1);
38   static_assert(width >= 8, "");
39   static_assert(height >= 8, "");
40   constexpr int rounding_bits = bitdepth - 8 + ((bitdepth == 12) ? 2 : 4);
41   for (int y = 0; y < height; ++y) {
42     for (int x = 0; x < width; ++x) {
43       const int difference = RightShiftWithRounding(
44           std::abs(pred_0[x] - pred_1[x]), rounding_bits);
45       const auto mask_value =
46           static_cast<uint8_t>(std::min(DivideBy16(difference) + 38, 64));
47       mask[x] = mask_is_inverse ? 64 - mask_value : mask_value;
48     }
49     pred_0 += width;
50     pred_1 += width;
51     mask += mask_stride;
52   }
53 }
54 
55 #define INIT_WEIGHT_MASK(width, height, bitdepth, w_index, h_index) \
56   dsp->weight_mask[w_index][h_index][0] =                           \
57       WeightMask_C<width, height, bitdepth, 0>;                     \
58   dsp->weight_mask[w_index][h_index][1] =                           \
59       WeightMask_C<width, height, bitdepth, 1>
60 
Init8bpp()61 void Init8bpp() {
62   Dsp* const dsp = dsp_internal::GetWritableDspTable(8);
63   assert(dsp != nullptr);
64 #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
65   INIT_WEIGHT_MASK(8, 8, 8, 0, 0);
66   INIT_WEIGHT_MASK(8, 16, 8, 0, 1);
67   INIT_WEIGHT_MASK(8, 32, 8, 0, 2);
68   INIT_WEIGHT_MASK(16, 8, 8, 1, 0);
69   INIT_WEIGHT_MASK(16, 16, 8, 1, 1);
70   INIT_WEIGHT_MASK(16, 32, 8, 1, 2);
71   INIT_WEIGHT_MASK(16, 64, 8, 1, 3);
72   INIT_WEIGHT_MASK(32, 8, 8, 2, 0);
73   INIT_WEIGHT_MASK(32, 16, 8, 2, 1);
74   INIT_WEIGHT_MASK(32, 32, 8, 2, 2);
75   INIT_WEIGHT_MASK(32, 64, 8, 2, 3);
76   INIT_WEIGHT_MASK(64, 16, 8, 3, 1);
77   INIT_WEIGHT_MASK(64, 32, 8, 3, 2);
78   INIT_WEIGHT_MASK(64, 64, 8, 3, 3);
79   INIT_WEIGHT_MASK(64, 128, 8, 3, 4);
80   INIT_WEIGHT_MASK(128, 64, 8, 4, 3);
81   INIT_WEIGHT_MASK(128, 128, 8, 4, 4);
82 #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
83   static_cast<void>(dsp);
84 #ifndef LIBGAV1_Dsp8bpp_WeightMask_8x8
85   INIT_WEIGHT_MASK(8, 8, 8, 0, 0);
86 #endif
87 #ifndef LIBGAV1_Dsp8bpp_WeightMask_8x16
88   INIT_WEIGHT_MASK(8, 16, 8, 0, 1);
89 #endif
90 #ifndef LIBGAV1_Dsp8bpp_WeightMask_8x32
91   INIT_WEIGHT_MASK(8, 32, 8, 0, 2);
92 #endif
93 #ifndef LIBGAV1_Dsp8bpp_WeightMask_16x8
94   INIT_WEIGHT_MASK(16, 8, 8, 1, 0);
95 #endif
96 #ifndef LIBGAV1_Dsp8bpp_WeightMask_16x16
97   INIT_WEIGHT_MASK(16, 16, 8, 1, 1);
98 #endif
99 #ifndef LIBGAV1_Dsp8bpp_WeightMask_16x32
100   INIT_WEIGHT_MASK(16, 32, 8, 1, 2);
101 #endif
102 #ifndef LIBGAV1_Dsp8bpp_WeightMask_16x64
103   INIT_WEIGHT_MASK(16, 64, 8, 1, 3);
104 #endif
105 #ifndef LIBGAV1_Dsp8bpp_WeightMask_32x8
106   INIT_WEIGHT_MASK(32, 8, 8, 2, 0);
107 #endif
108 #ifndef LIBGAV1_Dsp8bpp_WeightMask_32x16
109   INIT_WEIGHT_MASK(32, 16, 8, 2, 1);
110 #endif
111 #ifndef LIBGAV1_Dsp8bpp_WeightMask_32x32
112   INIT_WEIGHT_MASK(32, 32, 8, 2, 2);
113 #endif
114 #ifndef LIBGAV1_Dsp8bpp_WeightMask_32x64
115   INIT_WEIGHT_MASK(32, 64, 8, 2, 3);
116 #endif
117 #ifndef LIBGAV1_Dsp8bpp_WeightMask_64x16
118   INIT_WEIGHT_MASK(64, 16, 8, 3, 1);
119 #endif
120 #ifndef LIBGAV1_Dsp8bpp_WeightMask_64x32
121   INIT_WEIGHT_MASK(64, 32, 8, 3, 2);
122 #endif
123 #ifndef LIBGAV1_Dsp8bpp_WeightMask_64x64
124   INIT_WEIGHT_MASK(64, 64, 8, 3, 3);
125 #endif
126 #ifndef LIBGAV1_Dsp8bpp_WeightMask_64x128
127   INIT_WEIGHT_MASK(64, 128, 8, 3, 4);
128 #endif
129 #ifndef LIBGAV1_Dsp8bpp_WeightMask_128x64
130   INIT_WEIGHT_MASK(128, 64, 8, 4, 3);
131 #endif
132 #ifndef LIBGAV1_Dsp8bpp_WeightMask_128x128
133   INIT_WEIGHT_MASK(128, 128, 8, 4, 4);
134 #endif
135 #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
136 }
137 
138 #if LIBGAV1_MAX_BITDEPTH >= 10
Init10bpp()139 void Init10bpp() {
140   Dsp* const dsp = dsp_internal::GetWritableDspTable(10);
141   assert(dsp != nullptr);
142 #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
143   INIT_WEIGHT_MASK(8, 8, 10, 0, 0);
144   INIT_WEIGHT_MASK(8, 16, 10, 0, 1);
145   INIT_WEIGHT_MASK(8, 32, 10, 0, 2);
146   INIT_WEIGHT_MASK(16, 8, 10, 1, 0);
147   INIT_WEIGHT_MASK(16, 16, 10, 1, 1);
148   INIT_WEIGHT_MASK(16, 32, 10, 1, 2);
149   INIT_WEIGHT_MASK(16, 64, 10, 1, 3);
150   INIT_WEIGHT_MASK(32, 8, 10, 2, 0);
151   INIT_WEIGHT_MASK(32, 16, 10, 2, 1);
152   INIT_WEIGHT_MASK(32, 32, 10, 2, 2);
153   INIT_WEIGHT_MASK(32, 64, 10, 2, 3);
154   INIT_WEIGHT_MASK(64, 16, 10, 3, 1);
155   INIT_WEIGHT_MASK(64, 32, 10, 3, 2);
156   INIT_WEIGHT_MASK(64, 64, 10, 3, 3);
157   INIT_WEIGHT_MASK(64, 128, 10, 3, 4);
158   INIT_WEIGHT_MASK(128, 64, 10, 4, 3);
159   INIT_WEIGHT_MASK(128, 128, 10, 4, 4);
160 #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
161   static_cast<void>(dsp);
162 #ifndef LIBGAV1_Dsp10bpp_WeightMask_8x8
163   INIT_WEIGHT_MASK(8, 8, 10, 0, 0);
164 #endif
165 #ifndef LIBGAV1_Dsp10bpp_WeightMask_8x16
166   INIT_WEIGHT_MASK(8, 16, 10, 0, 1);
167 #endif
168 #ifndef LIBGAV1_Dsp10bpp_WeightMask_8x32
169   INIT_WEIGHT_MASK(8, 32, 10, 0, 2);
170 #endif
171 #ifndef LIBGAV1_Dsp10bpp_WeightMask_16x8
172   INIT_WEIGHT_MASK(16, 8, 10, 1, 0);
173 #endif
174 #ifndef LIBGAV1_Dsp10bpp_WeightMask_16x16
175   INIT_WEIGHT_MASK(16, 16, 10, 1, 1);
176 #endif
177 #ifndef LIBGAV1_Dsp10bpp_WeightMask_16x32
178   INIT_WEIGHT_MASK(16, 32, 10, 1, 2);
179 #endif
180 #ifndef LIBGAV1_Dsp10bpp_WeightMask_16x64
181   INIT_WEIGHT_MASK(16, 64, 10, 1, 3);
182 #endif
183 #ifndef LIBGAV1_Dsp10bpp_WeightMask_32x8
184   INIT_WEIGHT_MASK(32, 8, 10, 2, 0);
185 #endif
186 #ifndef LIBGAV1_Dsp10bpp_WeightMask_32x16
187   INIT_WEIGHT_MASK(32, 16, 10, 2, 1);
188 #endif
189 #ifndef LIBGAV1_Dsp10bpp_WeightMask_32x32
190   INIT_WEIGHT_MASK(32, 32, 10, 2, 2);
191 #endif
192 #ifndef LIBGAV1_Dsp10bpp_WeightMask_32x64
193   INIT_WEIGHT_MASK(32, 64, 10, 2, 3);
194 #endif
195 #ifndef LIBGAV1_Dsp10bpp_WeightMask_64x16
196   INIT_WEIGHT_MASK(64, 16, 10, 3, 1);
197 #endif
198 #ifndef LIBGAV1_Dsp10bpp_WeightMask_64x32
199   INIT_WEIGHT_MASK(64, 32, 10, 3, 2);
200 #endif
201 #ifndef LIBGAV1_Dsp10bpp_WeightMask_64x64
202   INIT_WEIGHT_MASK(64, 64, 10, 3, 3);
203 #endif
204 #ifndef LIBGAV1_Dsp10bpp_WeightMask_64x128
205   INIT_WEIGHT_MASK(64, 128, 10, 3, 4);
206 #endif
207 #ifndef LIBGAV1_Dsp10bpp_WeightMask_128x64
208   INIT_WEIGHT_MASK(128, 64, 10, 4, 3);
209 #endif
210 #ifndef LIBGAV1_Dsp10bpp_WeightMask_128x128
211   INIT_WEIGHT_MASK(128, 128, 10, 4, 4);
212 #endif
213 #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
214 }
215 #endif
216 
217 }  // namespace
218 
WeightMaskInit_C()219 void WeightMaskInit_C() {
220   Init8bpp();
221 #if LIBGAV1_MAX_BITDEPTH >= 10
222   Init10bpp();
223 #endif
224 }
225 
226 }  // namespace dsp
227 }  // namespace libgav1
228