Coverage Report

Created: 2026-04-01 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vvenc/source/Lib/CommonLib/MCTF.h
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
The copyright in this software is being made available under the Clear BSD
3
License, included below. No patent rights, trademark rights and/or 
4
other Intellectual Property Rights other than the copyrights concerning 
5
the Software are granted under this license.
6
7
The Clear BSD License
8
9
Copyright (c) 2019-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVenC Authors.
10
All rights reserved.
11
12
Redistribution and use in source and binary forms, with or without modification,
13
are permitted (subject to the limitations in the disclaimer below) provided that
14
the following conditions are met:
15
16
     * Redistributions of source code must retain the above copyright notice,
17
     this list of conditions and the following disclaimer.
18
19
     * Redistributions in binary form must reproduce the above copyright
20
     notice, this list of conditions and the following disclaimer in the
21
     documentation and/or other materials provided with the distribution.
22
23
     * Neither the name of the copyright holder nor the names of its
24
     contributors may be used to endorse or promote products derived from this
25
     software without specific prior written permission.
26
27
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
28
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
29
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
31
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
32
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
36
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
POSSIBILITY OF SUCH DAMAGE.
39
40
41
------------------------------------------------------------------------------------------- */
42
/** \file     MCTF.h
43
\brief    MCTF class (header)
44
*/
45
46
#pragma once
47
48
#include "CommonLib/Unit.h"
49
#include "EncoderLib/EncStage.h"
50
#include <sstream>
51
#include <map>
52
#include <deque>
53
#include <atomic>
54
55
namespace vvenc {
56
57
#if defined(TARGET_SIMD_X86)  && ENABLE_SIMD_OPT_MCTF
58
using namespace x86_simd;
59
#endif
60
#if defined(TARGET_SIMD_ARM)  && ENABLE_SIMD_OPT_MCTF
61
using namespace arm_simd;
62
#endif
63
64
class NoMallocThreadPool;
65
66
//! \ingroup EncoderLib
67
//! \{
68
69
double calcVarCore( const Pel* org, const ptrdiff_t origStride, const int w, const int h );
70
71
72
struct MotionVector
73
{
74
  int x, y;
75
  int error;
76
  uint16_t rmsme;
77
  double overlap;
78
79
0
  MotionVector() : x(0), y(0), error(INT_LEAST32_MAX), rmsme(UINT16_MAX) {}
80
81
0
  void set(int vectorX, int vectorY, int errorValue) { x = vectorX; y = vectorY; error = errorValue; }
82
};
83
84
template <class T>
85
struct Array2D
86
{
87
private:
88
  int m_width, m_height;
89
  std::vector< T > v;
90
public:
91
0
  Array2D() : m_width(0), m_height(0), v() { }
92
0
  Array2D(int width, int height, const T& value=T()) : m_width(0), m_height(0), v() { allocate(width, height, value); }
93
94
0
  int w() const { return m_width; }
95
0
  int h() const { return m_height; }
96
97
  void allocate(int width, int height, const T& value=T())
98
0
  {
99
0
    m_width=width;
100
0
    m_height=height;
101
0
    v.resize(std::size_t(m_width*m_height), value);
102
0
  }
103
104
  T& get(int x, int y)
105
0
  {
106
0
    assert(x<m_width && y<m_height);
107
0
    return v[y*m_width+x];
108
0
  }
109
110
  const T& get(int x, int y) const
111
0
  {
112
0
    assert(x<m_width && y<m_height);
113
0
    return v[y*m_width+x];
114
0
  }
115
};
116
117
struct TemporalFilterSourcePicInfo
118
{
119
0
  TemporalFilterSourcePicInfo() : picBuffer(), mvs(), index(0) { }
120
  PelStorage            picBuffer;
121
  Array2D<MotionVector> mvs;
122
  int                   index;
123
};
124
// ====================================================================================================================
125
// Class definition
126
// ====================================================================================================================
127
128
struct Picture;
129
130
class MCTF : public EncStage
131
{
132
public:
133
  MCTF( bool enableOpt = true );
134
  virtual ~MCTF();
135
136
  void init( const VVEncCfg& encCfg, bool isFinalPass, NoMallocThreadPool* threadPool );
137
138
protected:
139
  virtual void initPicture    ( Picture* pic );
140
  virtual void processPictures( const PicList& picList, AccessUnitList& auList, PicList& doneList, PicList& freeList );
141
private:
142
  void filter( const std::deque<Picture*>& picFifo, int filterIdx );
143
144
#if defined(TARGET_SIMD_X86) && ENABLE_SIMD_OPT_MCTF
145
  void initMCTF_X86();
146
  template <X86_VEXT vext>
147
  void _initMCTF_X86();
148
#endif
149
150
#if defined(TARGET_SIMD_ARM) && ENABLE_SIMD_OPT_MCTF
151
  void initMCTF_ARM();
152
  template <ARM_VEXT vext>
153
  void _initMCTF_ARM();
154
#endif
155
156
public:
157
  static const int16_t m_interpolationFilter4[16][4];
158
  static const int16_t m_interpolationFilter8[16][8];
159
160
  int ( *m_motionErrorLumaIntX )( const Pel* org, const ptrdiff_t origStride, const Pel* buf, const ptrdiff_t buffStride, const int w, const int h, const int besterror );
161
  int ( *m_motionErrorLumaInt8 )( const Pel* org, const ptrdiff_t origStride, const Pel* buf, const ptrdiff_t buffStride, const int w, const int h, const int besterror );
162
163
  int ( *m_motionErrorLumaFracX[2] )( const Pel* org, const ptrdiff_t origStride, const Pel* buf, const ptrdiff_t buffStride, const int w, const int h, const int16_t* xFilter, const int16_t* yFilter, const int bitDepth, const int besterror );
164
  int ( *m_motionErrorLumaFrac8[2] )( const Pel* org, const ptrdiff_t origStride, const Pel* buf, const ptrdiff_t buffStride, const int w, const int h, const int16_t* xFilter, const int16_t* yFilter, const int bitDepth, const int besterror );
165
166
  void( *m_applyFrac[MAX_NUM_CH][2] )( const Pel* org, const ptrdiff_t origStride, Pel* dst, const ptrdiff_t dstStride, const int bsx, const int bsy, const int16_t* xFilter, const int16_t* yFilter, const int bitDepth );
167
168
  void( *m_applyPlanarCorrection )( const Pel* refPel, const ptrdiff_t refStride, Pel* dstPel, const ptrdiff_t dstStride, const int32_t w, const int32_t h, const ClpRng& clpRng, const uint16_t motionError );
169
  void( *m_applyBlock )( const CPelBuf& src, PelBuf& dst, const CompArea& blk, const ClpRng& clpRng, const Pel** correctedPics, int numRefs, const int* verror, const double* refStrenghts, double weightScaling, double sigmaSq );
170
  double( *m_calcVar ) ( const Pel* org, const ptrdiff_t origStride, const int w, const int h );
171
172
private:
173
  static const double   m_chromaFactor;
174
  static const double   m_sigmaMultiplier;
175
  static const int      m_range;
176
  static const int      m_motionVectorFactor;
177
  static const int      m_padding;
178
  static const double   m_refStrengths[2][6];
179
  static const int      m_cuTreeThresh[4];
180
  static const double   m_cuTreeCenter;
181
182
  const VVEncCfg*       m_encCfg;
183
  NoMallocThreadPool*   m_threadPool;
184
  bool                  m_isFinalPass;
185
  int                   m_filterPoc;
186
  Area                  m_area;
187
  int                   m_MCTFSpeedVal;
188
  Picture*              m_lastPicIn;
189
  bool                  m_lowResFltSearch = false;  // TODO: use this to select high/low-res filter (6/4 tap) for motion search
190
  bool                  m_lowResFltApply  = false;  // TODO: use this to select high/low-res filter (6/4 tap) for actual application
191
  int                   m_searchPttrn     = 0;
192
  int                   m_mctfUnitSize;
193
194
  void subsampleLuma    (const PelStorage &input, PelStorage &output, const int factor = 2) const;
195
196
  int motionErrorLuma   (const PelStorage &orig, const PelStorage &buffer, const int x, const int y, int dx, int dy, const int bs, const int besterror) const;
197
198
  bool estimateLumaLn   ( std::atomic_int& blockX, std::atomic_int* prevLineX, Array2D<MotionVector> &mvs, const PelStorage &orig, const PelStorage &buffer, const int blockSize,
199
    const Array2D<MotionVector> *previous, const int factor, const bool doubleRes, int blockY, int bitDepth ) const;
200
201
  void motionEstimationLuma(Array2D<MotionVector> &mvs, const PelStorage &orig, const PelStorage &buffer, const int bs,
202
    const Array2D<MotionVector> *previous=0, const int factor = 1, const bool doubleRes = false) const;
203
204
  void bilateralFilter  (const PelStorage &orgPic, std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo, PelStorage &newOrgPic, double overallStrength) const;
205
206
  void xFinalizeBlkLine (const PelStorage &orgPic, std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo, PelStorage &newOrgPic, int yStart, const double sigmaSqCh[MAX_NUM_CH], double overallStrenght) const;
207
208
  void motionEstimationMCTF(Picture* curPic, std::deque<TemporalFilterSourcePicInfo>& srcFrameInfo, const PelStorage& origBuf, PelStorage& origSubsampled2, PelStorage& origSubsampled4, PelStorage& origSubsampled8, std::vector<double>& mvErr, double& minError, bool addLevel, bool calcErr);
209
210
}; // END CLASS DEFINITION MCTF
211
212
//! \}
213
214
} // namespace vvenc
215
216