xref: /aosp_15_r20/external/libgav1/src/dsp/obmc.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
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/obmc.h"
16*09537850SAkhilesh Sanikop 
17*09537850SAkhilesh Sanikop #include <cassert>
18*09537850SAkhilesh Sanikop #include <cstddef>
19*09537850SAkhilesh Sanikop #include <cstdint>
20*09537850SAkhilesh Sanikop 
21*09537850SAkhilesh Sanikop #include "src/dsp/dsp.h"
22*09537850SAkhilesh Sanikop #include "src/utils/common.h"
23*09537850SAkhilesh Sanikop #include "src/utils/constants.h"
24*09537850SAkhilesh Sanikop 
25*09537850SAkhilesh Sanikop namespace libgav1 {
26*09537850SAkhilesh Sanikop namespace dsp {
27*09537850SAkhilesh Sanikop namespace {
28*09537850SAkhilesh Sanikop 
29*09537850SAkhilesh Sanikop #include "src/dsp/obmc.inc"
30*09537850SAkhilesh Sanikop 
31*09537850SAkhilesh Sanikop // 7.11.3.10 (from top samples).
32*09537850SAkhilesh Sanikop template <typename Pixel>
OverlapBlendVertical_C(void * LIBGAV1_RESTRICT const prediction,const ptrdiff_t prediction_stride,const int width,const int height,const void * LIBGAV1_RESTRICT const obmc_prediction,const ptrdiff_t obmc_prediction_stride)33*09537850SAkhilesh Sanikop void OverlapBlendVertical_C(void* LIBGAV1_RESTRICT const prediction,
34*09537850SAkhilesh Sanikop                             const ptrdiff_t prediction_stride, const int width,
35*09537850SAkhilesh Sanikop                             const int height,
36*09537850SAkhilesh Sanikop                             const void* LIBGAV1_RESTRICT const obmc_prediction,
37*09537850SAkhilesh Sanikop                             const ptrdiff_t obmc_prediction_stride) {
38*09537850SAkhilesh Sanikop   auto* pred = static_cast<Pixel*>(prediction);
39*09537850SAkhilesh Sanikop   const ptrdiff_t pred_stride = prediction_stride / sizeof(Pixel);
40*09537850SAkhilesh Sanikop   const auto* obmc_pred = static_cast<const Pixel*>(obmc_prediction);
41*09537850SAkhilesh Sanikop   const ptrdiff_t obmc_pred_stride = obmc_prediction_stride / sizeof(Pixel);
42*09537850SAkhilesh Sanikop   const uint8_t* const mask = kObmcMask + height - 2;
43*09537850SAkhilesh Sanikop   assert(width >= 4);
44*09537850SAkhilesh Sanikop   assert(height >= 2);
45*09537850SAkhilesh Sanikop 
46*09537850SAkhilesh Sanikop   for (int y = 0; y < height; ++y) {
47*09537850SAkhilesh Sanikop     const uint8_t mask_value = mask[y];
48*09537850SAkhilesh Sanikop     for (int x = 0; x < width; ++x) {
49*09537850SAkhilesh Sanikop       pred[x] = static_cast<Pixel>(RightShiftWithRounding(
50*09537850SAkhilesh Sanikop           mask_value * pred[x] + (64 - mask_value) * obmc_pred[x], 6));
51*09537850SAkhilesh Sanikop     }
52*09537850SAkhilesh Sanikop     pred += pred_stride;
53*09537850SAkhilesh Sanikop     obmc_pred += obmc_pred_stride;
54*09537850SAkhilesh Sanikop   }
55*09537850SAkhilesh Sanikop }
56*09537850SAkhilesh Sanikop 
57*09537850SAkhilesh Sanikop // 7.11.3.10 (from left samples).
58*09537850SAkhilesh Sanikop template <typename Pixel>
OverlapBlendHorizontal_C(void * LIBGAV1_RESTRICT const prediction,const ptrdiff_t prediction_stride,const int width,const int height,const void * LIBGAV1_RESTRICT const obmc_prediction,const ptrdiff_t obmc_prediction_stride)59*09537850SAkhilesh Sanikop void OverlapBlendHorizontal_C(
60*09537850SAkhilesh Sanikop     void* LIBGAV1_RESTRICT const prediction, const ptrdiff_t prediction_stride,
61*09537850SAkhilesh Sanikop     const int width, const int height,
62*09537850SAkhilesh Sanikop     const void* LIBGAV1_RESTRICT const obmc_prediction,
63*09537850SAkhilesh Sanikop     const ptrdiff_t obmc_prediction_stride) {
64*09537850SAkhilesh Sanikop   auto* pred = static_cast<Pixel*>(prediction);
65*09537850SAkhilesh Sanikop   const ptrdiff_t pred_stride = prediction_stride / sizeof(Pixel);
66*09537850SAkhilesh Sanikop   const auto* obmc_pred = static_cast<const Pixel*>(obmc_prediction);
67*09537850SAkhilesh Sanikop   const ptrdiff_t obmc_pred_stride = obmc_prediction_stride / sizeof(Pixel);
68*09537850SAkhilesh Sanikop   const uint8_t* const mask = kObmcMask + width - 2;
69*09537850SAkhilesh Sanikop   assert(width >= 2);
70*09537850SAkhilesh Sanikop   assert(height >= 4);
71*09537850SAkhilesh Sanikop 
72*09537850SAkhilesh Sanikop   for (int y = 0; y < height; ++y) {
73*09537850SAkhilesh Sanikop     for (int x = 0; x < width; ++x) {
74*09537850SAkhilesh Sanikop       const uint8_t mask_value = mask[x];
75*09537850SAkhilesh Sanikop       pred[x] = static_cast<Pixel>(RightShiftWithRounding(
76*09537850SAkhilesh Sanikop           mask_value * pred[x] + (64 - mask_value) * obmc_pred[x], 6));
77*09537850SAkhilesh Sanikop     }
78*09537850SAkhilesh Sanikop     pred += pred_stride;
79*09537850SAkhilesh Sanikop     obmc_pred += obmc_pred_stride;
80*09537850SAkhilesh Sanikop   }
81*09537850SAkhilesh Sanikop }
82*09537850SAkhilesh Sanikop 
Init8bpp()83*09537850SAkhilesh Sanikop void Init8bpp() {
84*09537850SAkhilesh Sanikop   Dsp* const dsp = dsp_internal::GetWritableDspTable(8);
85*09537850SAkhilesh Sanikop   assert(dsp != nullptr);
86*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
87*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionVertical] = OverlapBlendVertical_C<uint8_t>;
88*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionHorizontal] = OverlapBlendHorizontal_C<uint8_t>;
89*09537850SAkhilesh Sanikop #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
90*09537850SAkhilesh Sanikop   static_cast<void>(dsp);
91*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp8bpp_ObmcVertical
92*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionVertical] = OverlapBlendVertical_C<uint8_t>;
93*09537850SAkhilesh Sanikop #endif
94*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp8bpp_ObmcHorizontal
95*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionHorizontal] = OverlapBlendHorizontal_C<uint8_t>;
96*09537850SAkhilesh Sanikop #endif
97*09537850SAkhilesh Sanikop #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
98*09537850SAkhilesh Sanikop }
99*09537850SAkhilesh Sanikop 
100*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
Init10bpp()101*09537850SAkhilesh Sanikop void Init10bpp() {
102*09537850SAkhilesh Sanikop   Dsp* const dsp = dsp_internal::GetWritableDspTable(10);
103*09537850SAkhilesh Sanikop   assert(dsp != nullptr);
104*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
105*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionVertical] = OverlapBlendVertical_C<uint16_t>;
106*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionHorizontal] =
107*09537850SAkhilesh Sanikop       OverlapBlendHorizontal_C<uint16_t>;
108*09537850SAkhilesh Sanikop #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
109*09537850SAkhilesh Sanikop   static_cast<void>(dsp);
110*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp10bpp_ObmcVertical
111*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionVertical] = OverlapBlendVertical_C<uint16_t>;
112*09537850SAkhilesh Sanikop #endif
113*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp10bpp_ObmcHorizontal
114*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionHorizontal] =
115*09537850SAkhilesh Sanikop       OverlapBlendHorizontal_C<uint16_t>;
116*09537850SAkhilesh Sanikop #endif
117*09537850SAkhilesh Sanikop #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
118*09537850SAkhilesh Sanikop }
119*09537850SAkhilesh Sanikop #endif  // LIBGAV1_MAX_BITDEPTH >= 10
120*09537850SAkhilesh Sanikop 
121*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
Init12bpp()122*09537850SAkhilesh Sanikop void Init12bpp() {
123*09537850SAkhilesh Sanikop   Dsp* const dsp = dsp_internal::GetWritableDspTable(12);
124*09537850SAkhilesh Sanikop   assert(dsp != nullptr);
125*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
126*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionVertical] = OverlapBlendVertical_C<uint16_t>;
127*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionHorizontal] =
128*09537850SAkhilesh Sanikop       OverlapBlendHorizontal_C<uint16_t>;
129*09537850SAkhilesh Sanikop #else  // !LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
130*09537850SAkhilesh Sanikop   static_cast<void>(dsp);
131*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp12bpp_ObmcVertical
132*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionVertical] = OverlapBlendVertical_C<uint16_t>;
133*09537850SAkhilesh Sanikop #endif
134*09537850SAkhilesh Sanikop #ifndef LIBGAV1_Dsp12bpp_ObmcHorizontal
135*09537850SAkhilesh Sanikop   dsp->obmc_blend[kObmcDirectionHorizontal] =
136*09537850SAkhilesh Sanikop       OverlapBlendHorizontal_C<uint16_t>;
137*09537850SAkhilesh Sanikop #endif
138*09537850SAkhilesh Sanikop #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS
139*09537850SAkhilesh Sanikop }
140*09537850SAkhilesh Sanikop #endif  // LIBGAV1_MAX_BITDEPTH == 12
141*09537850SAkhilesh Sanikop 
142*09537850SAkhilesh Sanikop }  // namespace
143*09537850SAkhilesh Sanikop 
ObmcInit_C()144*09537850SAkhilesh Sanikop void ObmcInit_C() {
145*09537850SAkhilesh Sanikop   Init8bpp();
146*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH >= 10
147*09537850SAkhilesh Sanikop   Init10bpp();
148*09537850SAkhilesh Sanikop #endif
149*09537850SAkhilesh Sanikop #if LIBGAV1_MAX_BITDEPTH == 12
150*09537850SAkhilesh Sanikop   Init12bpp();
151*09537850SAkhilesh Sanikop #endif
152*09537850SAkhilesh Sanikop }
153*09537850SAkhilesh Sanikop 
154*09537850SAkhilesh Sanikop }  // namespace dsp
155*09537850SAkhilesh Sanikop }  // namespace libgav1
156