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