1*09537850SAkhilesh Sanikop // Copyright 2019 The libgav1 Authors
2*09537850SAkhilesh Sanikop //
3*09537850SAkhilesh Sanikop // Licensed under the Apache License, Version 2.0 (the "License");
4*09537850SAkhilesh Sanikop // you may not use this file except in compliance with the License.
5*09537850SAkhilesh Sanikop // You may obtain a copy of the License at
6*09537850SAkhilesh Sanikop //
7*09537850SAkhilesh Sanikop // http://www.apache.org/licenses/LICENSE-2.0
8*09537850SAkhilesh Sanikop //
9*09537850SAkhilesh Sanikop // Unless required by applicable law or agreed to in writing, software
10*09537850SAkhilesh Sanikop // distributed under the License is distributed on an "AS IS" BASIS,
11*09537850SAkhilesh Sanikop // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*09537850SAkhilesh Sanikop // See the License for the specific language governing permissions and
13*09537850SAkhilesh Sanikop // limitations under the License.
14*09537850SAkhilesh Sanikop
15*09537850SAkhilesh Sanikop #include "src/dsp/average_blend.h"
16*09537850SAkhilesh Sanikop
17*09537850SAkhilesh Sanikop #include <cassert>
18*09537850SAkhilesh Sanikop #include <cstddef>
19*09537850SAkhilesh Sanikop #include <cstdint>
20*09537850SAkhilesh Sanikop #include <type_traits>
21*09537850SAkhilesh Sanikop
22*09537850SAkhilesh Sanikop #include "src/dsp/dsp.h"
23*09537850SAkhilesh Sanikop #include "src/utils/common.h"
24*09537850SAkhilesh Sanikop
25*09537850SAkhilesh Sanikop namespace libgav1 {
26*09537850SAkhilesh Sanikop namespace dsp {
27*09537850SAkhilesh Sanikop namespace {
28*09537850SAkhilesh Sanikop
29*09537850SAkhilesh Sanikop 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*09537850SAkhilesh Sanikop void AverageBlend_C(const void* LIBGAV1_RESTRICT prediction_0,
31*09537850SAkhilesh Sanikop const void* LIBGAV1_RESTRICT prediction_1, const int width,
32*09537850SAkhilesh Sanikop const int height, void* const dest,
33*09537850SAkhilesh Sanikop const ptrdiff_t dest_stride) {
34*09537850SAkhilesh Sanikop // 7.11.3.2 Rounding variables derivation process
35*09537850SAkhilesh Sanikop // 2 * FILTER_BITS(7) - (InterRound0(3|5) + InterRound1(7))
36*09537850SAkhilesh Sanikop constexpr int inter_post_round_bits = (bitdepth == 12) ? 2 : 4;
37*09537850SAkhilesh Sanikop using PredType =
38*09537850SAkhilesh Sanikop typename std::conditional<bitdepth == 8, int16_t, uint16_t>::type;
39*09537850SAkhilesh Sanikop const auto* pred_0 = static_cast<const PredType*>(prediction_0);
40*09537850SAkhilesh Sanikop const auto* pred_1 = static_cast<const PredType*>(prediction_1);
41*09537850SAkhilesh Sanikop auto* dst = static_cast<Pixel*>(dest);
42*09537850SAkhilesh Sanikop const ptrdiff_t dst_stride = dest_stride / sizeof(Pixel);
43*09537850SAkhilesh Sanikop
44*09537850SAkhilesh Sanikop int y = 0;
45*09537850SAkhilesh Sanikop do {
46*09537850SAkhilesh Sanikop int x = 0;
47*09537850SAkhilesh Sanikop do {
48*09537850SAkhilesh Sanikop // See warp.cc and convolve.cc for detailed prediction ranges.
49*09537850SAkhilesh Sanikop int res = pred_0[x] + pred_1[x];
50*09537850SAkhilesh Sanikop res -= (bitdepth == 8) ? 0 : kCompoundOffset + kCompoundOffset;
51*09537850SAkhilesh Sanikop dst[x] = static_cast<Pixel>(
52*09537850SAkhilesh Sanikop Clip3(RightShiftWithRounding(res, inter_post_round_bits + 1), 0,
53*09537850SAkhilesh Sanikop (1 << bitdepth) - 1));
54*09537850SAkhilesh Sanikop } while (++x < width);
55*09537850SAkhilesh Sanikop
56*09537850SAkhilesh Sanikop dst += dst_stride;
57*09537850SAkhilesh Sanikop pred_0 += width;
58*09537850SAkhilesh Sanikop pred_1 += width;
59*09537850SAkhilesh Sanikop } while (++y < height);
60*09537850SAkhilesh Sanikop }
61*09537850SAkhilesh Sanikop
Init8bpp()62*09537850SAkhilesh Sanikop void Init8bpp() {
63*09537850SAkhilesh Sanikop Dsp* const dsp = dsp_internal::GetWritableDspTable(8);
64*09537850SAkhilesh Sanikop assert(dsp != nullptr);
65*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
66*09537850SAkhilesh Sanikop dsp->average_blend = AverageBlend_C<8, uint8_t>;
67*09537850SAkhilesh Sanikop #else // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
68*09537850SAkhilesh Sanikop static_cast<void>(dsp);
69*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp8bpp_AverageBlend
70*09537850SAkhilesh Sanikop dsp->average_blend = AverageBlend_C<8, uint8_t>;
71*09537850SAkhilesh Sanikop #endif
72*09537850SAkhilesh Sanikop #endif // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
73*09537850SAkhilesh Sanikop }
74*09537850SAkhilesh Sanikop
75*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
Init10bpp()76*09537850SAkhilesh Sanikop void Init10bpp() {
77*09537850SAkhilesh Sanikop Dsp* const dsp = dsp_internal::GetWritableDspTable(10);
78*09537850SAkhilesh Sanikop assert(dsp != nullptr);
79*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
80*09537850SAkhilesh Sanikop dsp->average_blend = AverageBlend_C<10, uint16_t>;
81*09537850SAkhilesh Sanikop #else // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
82*09537850SAkhilesh Sanikop static_cast<void>(dsp);
83*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp10bpp_AverageBlend
84*09537850SAkhilesh Sanikop dsp->average_blend = AverageBlend_C<10, uint16_t>;
85*09537850SAkhilesh Sanikop #endif
86*09537850SAkhilesh Sanikop #endif // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
87*09537850SAkhilesh Sanikop }
88*09537850SAkhilesh Sanikop #endif
89*09537850SAkhilesh Sanikop
90*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
Init12bpp()91*09537850SAkhilesh Sanikop void Init12bpp() {
92*09537850SAkhilesh Sanikop Dsp* const dsp = dsp_internal::GetWritableDspTable(12);
93*09537850SAkhilesh Sanikop assert(dsp != nullptr);
94*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
95*09537850SAkhilesh Sanikop dsp->average_blend = AverageBlend_C<12, uint16_t>;
96*09537850SAkhilesh Sanikop #else // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
97*09537850SAkhilesh Sanikop static_cast<void>(dsp);
98*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp12bpp_AverageBlend
99*09537850SAkhilesh Sanikop dsp->average_blend = AverageBlend_C<12, uint16_t>;
100*09537850SAkhilesh Sanikop #endif
101*09537850SAkhilesh Sanikop #endif // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
102*09537850SAkhilesh Sanikop }
103*09537850SAkhilesh Sanikop #endif
104*09537850SAkhilesh Sanikop
105*09537850SAkhilesh Sanikop } // namespace
106*09537850SAkhilesh Sanikop
AverageBlendInit_C()107*09537850SAkhilesh Sanikop void AverageBlendInit_C() {
108*09537850SAkhilesh Sanikop Init8bpp();
109*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
110*09537850SAkhilesh Sanikop Init10bpp();
111*09537850SAkhilesh Sanikop #endif
112*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
113*09537850SAkhilesh Sanikop Init12bpp();
114*09537850SAkhilesh Sanikop #endif
115*09537850SAkhilesh Sanikop }
116*09537850SAkhilesh Sanikop
117*09537850SAkhilesh Sanikop } // namespace dsp
118*09537850SAkhilesh Sanikop } // namespace libgav1
119