xref: /aosp_15_r20/external/libgav1/src/dsp/motion_field_projection.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1*09537850SAkhilesh Sanikop // Copyright 2020 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/motion_field_projection.h"
16*09537850SAkhilesh Sanikop 
17*09537850SAkhilesh Sanikop #include <algorithm>
18*09537850SAkhilesh Sanikop #include <cassert>
19*09537850SAkhilesh Sanikop #include <cstddef>
20*09537850SAkhilesh Sanikop #include <cstdint>
21*09537850SAkhilesh Sanikop 
22*09537850SAkhilesh Sanikop #include "src/dsp/dsp.h"
23*09537850SAkhilesh Sanikop #include "src/utils/common.h"
24*09537850SAkhilesh Sanikop #include "src/utils/constants.h"
25*09537850SAkhilesh Sanikop #include "src/utils/reference_info.h"
26*09537850SAkhilesh Sanikop #include "src/utils/types.h"
27*09537850SAkhilesh Sanikop 
28*09537850SAkhilesh Sanikop namespace libgav1 {
29*09537850SAkhilesh Sanikop namespace dsp {
30*09537850SAkhilesh Sanikop namespace {
31*09537850SAkhilesh Sanikop 
32*09537850SAkhilesh Sanikop // Silence unused function warnings when MotionFieldProjectionKernel_C is
33*09537850SAkhilesh Sanikop // not used.
34*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS || \
35*09537850SAkhilesh Sanikop     !defined(LIBGAV1_Dsp8bpp_MotionFieldProjectionKernel)
36*09537850SAkhilesh Sanikop 
37*09537850SAkhilesh Sanikop // 7.9.2.
MotionFieldProjectionKernel_C(const ReferenceInfo & reference_info,int reference_to_current_with_sign,int dst_sign,int y8_start,int y8_end,int x8_start,int x8_end,TemporalMotionField * motion_field)38*09537850SAkhilesh Sanikop void MotionFieldProjectionKernel_C(const ReferenceInfo& reference_info,
39*09537850SAkhilesh Sanikop                                    int reference_to_current_with_sign,
40*09537850SAkhilesh Sanikop                                    int dst_sign, int y8_start, int y8_end,
41*09537850SAkhilesh Sanikop                                    int x8_start, int x8_end,
42*09537850SAkhilesh Sanikop                                    TemporalMotionField* motion_field) {
43*09537850SAkhilesh Sanikop   const ptrdiff_t stride = motion_field->mv.columns();
44*09537850SAkhilesh Sanikop   // The column range has to be offset by kProjectionMvMaxHorizontalOffset since
45*09537850SAkhilesh Sanikop   // coordinates in that range could end up being position_x8 because of
46*09537850SAkhilesh Sanikop   // projection.
47*09537850SAkhilesh Sanikop   const int adjusted_x8_start =
48*09537850SAkhilesh Sanikop       std::max(x8_start - kProjectionMvMaxHorizontalOffset, 0);
49*09537850SAkhilesh Sanikop   const int adjusted_x8_end = std::min(
50*09537850SAkhilesh Sanikop       x8_end + kProjectionMvMaxHorizontalOffset, static_cast<int>(stride));
51*09537850SAkhilesh Sanikop   const int8_t* const reference_offsets =
52*09537850SAkhilesh Sanikop       reference_info.relative_distance_to.data();
53*09537850SAkhilesh Sanikop   const bool* const skip_references = reference_info.skip_references.data();
54*09537850SAkhilesh Sanikop   const int16_t* const projection_divisions =
55*09537850SAkhilesh Sanikop       reference_info.projection_divisions.data();
56*09537850SAkhilesh Sanikop   const ReferenceFrameType* source_reference_types =
57*09537850SAkhilesh Sanikop       &reference_info.motion_field_reference_frame[y8_start][0];
58*09537850SAkhilesh Sanikop   const MotionVector* mv = &reference_info.motion_field_mv[y8_start][0];
59*09537850SAkhilesh Sanikop   int8_t* dst_reference_offset = motion_field->reference_offset[y8_start];
60*09537850SAkhilesh Sanikop   MotionVector* dst_mv = motion_field->mv[y8_start];
61*09537850SAkhilesh Sanikop   assert(stride == motion_field->reference_offset.columns());
62*09537850SAkhilesh Sanikop   assert((y8_start & 7) == 0);
63*09537850SAkhilesh Sanikop 
64*09537850SAkhilesh Sanikop   int y8 = y8_start;
65*09537850SAkhilesh Sanikop   do {
66*09537850SAkhilesh Sanikop     const int y8_floor = (y8 & ~7) - y8;
67*09537850SAkhilesh Sanikop     const int y8_ceiling = std::min(y8_end - y8, y8_floor + 8);
68*09537850SAkhilesh Sanikop     int x8 = adjusted_x8_start;
69*09537850SAkhilesh Sanikop     do {
70*09537850SAkhilesh Sanikop       const int source_reference_type = source_reference_types[x8];
71*09537850SAkhilesh Sanikop       if (skip_references[source_reference_type]) continue;
72*09537850SAkhilesh Sanikop       MotionVector projection_mv;
73*09537850SAkhilesh Sanikop       // reference_to_current_with_sign could be 0.
74*09537850SAkhilesh Sanikop       GetMvProjection(mv[x8], reference_to_current_with_sign,
75*09537850SAkhilesh Sanikop                       projection_divisions[source_reference_type],
76*09537850SAkhilesh Sanikop                       &projection_mv);
77*09537850SAkhilesh Sanikop       // Do not update the motion vector if the block position is not valid or
78*09537850SAkhilesh Sanikop       // if position_x8 is outside the current range of x8_start and x8_end.
79*09537850SAkhilesh Sanikop       // Note that position_y8 will always be within the range of y8_start and
80*09537850SAkhilesh Sanikop       // y8_end.
81*09537850SAkhilesh Sanikop       const int position_y8 = Project(0, projection_mv.mv[0], dst_sign);
82*09537850SAkhilesh Sanikop       if (position_y8 < y8_floor || position_y8 >= y8_ceiling) continue;
83*09537850SAkhilesh Sanikop       const int x8_base = x8 & ~7;
84*09537850SAkhilesh Sanikop       const int x8_floor =
85*09537850SAkhilesh Sanikop           std::max(x8_start, x8_base - kProjectionMvMaxHorizontalOffset);
86*09537850SAkhilesh Sanikop       const int x8_ceiling =
87*09537850SAkhilesh Sanikop           std::min(x8_end, x8_base + 8 + kProjectionMvMaxHorizontalOffset);
88*09537850SAkhilesh Sanikop       const int position_x8 = Project(x8, projection_mv.mv[1], dst_sign);
89*09537850SAkhilesh Sanikop       if (position_x8 < x8_floor || position_x8 >= x8_ceiling) continue;
90*09537850SAkhilesh Sanikop       dst_mv[position_y8 * stride + position_x8] = mv[x8];
91*09537850SAkhilesh Sanikop       dst_reference_offset[position_y8 * stride + position_x8] =
92*09537850SAkhilesh Sanikop           reference_offsets[source_reference_type];
93*09537850SAkhilesh Sanikop     } while (++x8 < adjusted_x8_end);
94*09537850SAkhilesh Sanikop     source_reference_types += stride;
95*09537850SAkhilesh Sanikop     mv += stride;
96*09537850SAkhilesh Sanikop     dst_reference_offset += stride;
97*09537850SAkhilesh Sanikop     dst_mv += stride;
98*09537850SAkhilesh Sanikop   } while (++y8 < y8_end);
99*09537850SAkhilesh Sanikop }
100*09537850SAkhilesh Sanikop 
101*09537850SAkhilesh Sanikop #endif  // LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS ||
102*09537850SAkhilesh Sanikop         // !defined(LIBGAV1_Dsp8bpp_MotionFieldProjectionKernel)
103*09537850SAkhilesh Sanikop 
104*09537850SAkhilesh Sanikop }  // namespace
105*09537850SAkhilesh Sanikop 
MotionFieldProjectionInit_C()106*09537850SAkhilesh Sanikop void MotionFieldProjectionInit_C() {
107*09537850SAkhilesh Sanikop #if LIBGAV1_ENABLE_ALL_DSP_FUNCTIONS || \
108*09537850SAkhilesh Sanikop     !defined(LIBGAV1_Dsp8bpp_MotionFieldProjectionKernel)
109*09537850SAkhilesh Sanikop   Dsp* const dsp = dsp_internal::GetWritableDspTable(kBitdepth8);
110*09537850SAkhilesh Sanikop   assert(dsp != nullptr);
111*09537850SAkhilesh Sanikop   dsp->motion_field_projection_kernel = MotionFieldProjectionKernel_C;
112*09537850SAkhilesh Sanikop #endif
113*09537850SAkhilesh Sanikop }
114*09537850SAkhilesh Sanikop 
115*09537850SAkhilesh Sanikop }  // namespace dsp
116*09537850SAkhilesh Sanikop }  // namespace libgav1
117