xref: /aosp_15_r20/external/libgav1/src/dsp/distance_weighted_blend.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
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/distance_weighted_blend.h"
16 
17 #include <cassert>
18 #include <cstddef>
19 #include <cstdint>
20 #include <type_traits>
21 
22 #include "src/dsp/dsp.h"
23 #include "src/utils/common.h"
24 
25 namespace libgav1 {
26 namespace dsp {
27 namespace {
28 
29 template <int bitdepth, typename Pixel>
DistanceWeightedBlend_C(const void * LIBGAV1_RESTRICT prediction_0,const void * LIBGAV1_RESTRICT prediction_1,const uint8_t weight_0,const uint8_t weight_1,const int width,const int height,void * LIBGAV1_RESTRICT const dest,const ptrdiff_t dest_stride)30 void DistanceWeightedBlend_C(const void* LIBGAV1_RESTRICT prediction_0,
31                              const void* LIBGAV1_RESTRICT prediction_1,
32                              const uint8_t weight_0, const uint8_t weight_1,
33                              const int width, const int height,
34                              void* LIBGAV1_RESTRICT const dest,
35                              const ptrdiff_t dest_stride) {
36   // 7.11.3.2 Rounding variables derivation process
37   //   2 * FILTER_BITS(7) - (InterRound0(3|5) + InterRound1(7))
38   constexpr int inter_post_round_bits = (bitdepth == 12) ? 2 : 4;
39   using PredType =
40       typename std::conditional<bitdepth == 8, int16_t, uint16_t>::type;
41   const auto* pred_0 = static_cast<const PredType*>(prediction_0);
42   const auto* pred_1 = static_cast<const PredType*>(prediction_1);
43   auto* dst = static_cast<Pixel*>(dest);
44   const ptrdiff_t dst_stride = dest_stride / sizeof(Pixel);
45 
46   int y = 0;
47   do {
48     int x = 0;
49     do {
50       // See warp.cc and convolve.cc for detailed prediction ranges.
51       // weight_0 + weight_1 = 16.
52       int res = pred_0[x] * weight_0 + pred_1[x] * weight_1;
53       res -= (bitdepth == 8) ? 0 : kCompoundOffset * 16;
54       dst[x] = static_cast<Pixel>(
55           Clip3(RightShiftWithRounding(res, inter_post_round_bits + 4), 0,
56                 (1 << bitdepth) - 1));
57     } while (++x < width);
58 
59     dst += dst_stride;
60     pred_0 += width;
61     pred_1 += width;
62   } while (++y < height);
63 }
64 
Init8bpp()65 void Init8bpp() {
66   Dsp* const dsp = dsp_internal::GetWritableDspTable(8);
67   assert(dsp != nullptr);
68 #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
69   dsp->distance_weighted_blend = DistanceWeightedBlend_C<8, uint8_t>;
70 #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
71   static_cast<void>(dsp);
72 #ifndef LIBGAV1_Dsp8bpp_DistanceWeightedBlend
73   dsp->distance_weighted_blend = DistanceWeightedBlend_C<8, uint8_t>;
74 #endif
75 #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
76 }
77 
78 #if LIBGAV1_MAX_BITDEPTH >= 10
Init10bpp()79 void Init10bpp() {
80   Dsp* const dsp = dsp_internal::GetWritableDspTable(10);
81   assert(dsp != nullptr);
82 #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
83   dsp->distance_weighted_blend = DistanceWeightedBlend_C<10, uint16_t>;
84 #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
85   static_cast<void>(dsp);
86 #ifndef LIBGAV1_Dsp10bpp_DistanceWeightedBlend
87   dsp->distance_weighted_blend = DistanceWeightedBlend_C<10, uint16_t>;
88 #endif
89 #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
90 }
91 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
92 
93 #if LIBGAV1_MAX_BITDEPTH == 12
Init12bpp()94 void Init12bpp() {
95   Dsp* const dsp = dsp_internal::GetWritableDspTable(12);
96   assert(dsp != nullptr);
97 #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
98   dsp->distance_weighted_blend = DistanceWeightedBlend_C<12, uint16_t>;
99 #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
100   static_cast<void>(dsp);
101 #ifndef LIBGAV1_Dsp12bpp_DistanceWeightedBlend
102   dsp->distance_weighted_blend = DistanceWeightedBlend_C<12, uint16_t>;
103 #endif
104 #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
105 }
106 #endif  // LIBGAV1_MAX_BITDEPTH == 12
107 
108 }  // namespace
109 
DistanceWeightedBlendInit_C()110 void DistanceWeightedBlendInit_C() {
111   Init8bpp();
112 #if LIBGAV1_MAX_BITDEPTH >= 10
113   Init10bpp();
114 #endif
115 #if LIBGAV1_MAX_BITDEPTH == 12
116   Init12bpp();
117 #endif
118 }
119 
120 }  // namespace dsp
121 }  // namespace libgav1
122