Coverage Report

Created: 2026-10-28 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/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 "EncoderLib/SEIFilmGrainAnalyzer.h"
51
#include <sstream>
52
#include <map>
53
#include <deque>
54
#include <atomic>
55
56
namespace vvenc {
57
58
#if defined(TARGET_SIMD_X86)  && ENABLE_SIMD_OPT_MCTF
59
using namespace x86_simd;
60
#endif
61
#if defined(TARGET_SIMD_ARM)  && ENABLE_SIMD_OPT_MCTF
62
using namespace arm_simd;
63
#endif
64
65
class NoMallocThreadPool;
66
67
//! \ingroup EncoderLib
68
//! \{
69
70
double calcVarCore( const Pel* org, const ptrdiff_t origStride, const int w, const int h );
71
72
73
struct MotionVector
74
{
75
  int x, y;
76
  int error;
77
  uint16_t rmsme;
78
  double overlap;
79
80
0
  MotionVector() : x(0), y(0), error(INT_LEAST32_MAX), rmsme(UINT16_MAX) {}
81
82
0
  void set(int vectorX, int vectorY, int errorValue) { x = vectorX; y = vectorY; error = errorValue; }
83
};
84
85
template <class T>
86
struct Array2D
87
{
88
private:
89
  int m_width, m_height;
90
  std::vector< T > v;
91
public:
92
0
  Array2D() : m_width(0), m_height(0), v() { }
93
0
  Array2D(int width, int height, const T& value=T()) : m_width(0), m_height(0), v() { allocate(width, height, value); }
94
95
0
  int w() const { return m_width; }
96
0
  int h() const { return m_height; }
97
98
  void allocate(int width, int height, const T& value=T())
99
0
  {
100
0
    m_width=width;
101
0
    m_height=height;
102
0
    v.resize(std::size_t(m_width*m_height), value);
103
0
  }
104
105
  T& get(int x, int y)
106
0
  {
107
0
    assert(x<m_width && y<m_height);
108
0
    return v[y*m_width+x];
109
0
  }
110
111
  const T& get(int x, int y) const
112
0
  {
113
0
    assert(x<m_width && y<m_height);
114
0
    return v[y*m_width+x];
115
0
  }
116
};
117
118
struct TemporalFilterSourcePicInfo
119
{
120
0
  TemporalFilterSourcePicInfo() : picBuffer(), mvs(), index(0) { }
121
  PelStorage            picBuffer;
122
  Array2D<MotionVector> mvs;
123
  int                   index;
124
};
125
// ====================================================================================================================
126
// Class definition
127
// ====================================================================================================================
128
129
struct Picture;
130
131
class MCTF : public EncStage
132
{
133
public:
134
  MCTF( bool enableOpt = true );
135
  virtual ~MCTF();
136
137
  void init( const VVEncCfg& encCfg, bool isFinalPass, NoMallocThreadPool* threadPool );
138
139
protected:
140
  virtual void initPicture    ( Picture* pic );
141
  virtual void processPictures( const PicList& picList, AccessUnitList& auList, PicList& doneList, PicList& freeList );
142
private:
143
  void filter( const std::deque<Picture*>& picFifo, int filterIdx );
144
145
#if defined(TARGET_SIMD_X86) && ENABLE_SIMD_OPT_MCTF
146
  void initMCTF_X86();
147
  template <X86_VEXT vext>
148
  void _initMCTF_X86();
149
#endif
150
151
#if defined(TARGET_SIMD_ARM) && ENABLE_SIMD_OPT_MCTF
152
  void initMCTF_ARM();
153
  template <ARM_VEXT vext>
154
  void _initMCTF_ARM();
155
#endif
156
157
public:
158
  static const int16_t m_interpolationFilter4[16][4];
159
  static const int16_t m_interpolationFilter8[16][8];
160
161
  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 );
162
  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 );
163
164
  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 );
165
  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 );
166
167
  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 );
168
169
  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 );
170
  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 );
171
  double( *m_calcVar ) ( const Pel* org, const ptrdiff_t origStride, const int w, const int h );
172
173
  // The CU-tree look-ahead reuses the motion search.
174
  void motionEstimationLuma(Array2D<MotionVector> &mvs, const PelStorage &orig, const PelStorage &buffer, const int refMargin, const int bs,
175
    const Array2D<MotionVector> *previous=0, const int factor = 1, const bool doubleRes = false) const;
176
177
private:
178
  static const double   m_chromaFactor;
179
  static const double   m_sigmaMultiplier;
180
  static const int      m_range;
181
  static const int      m_motionVectorFactor;
182
  static const int      m_padding;
183
  static const double   m_refStrengths[2][6];
184
  static const int      m_cuTreeThresh[4];
185
  static const double   m_cuTreeCenter;
186
187
  const VVEncCfg*       m_encCfg;
188
  NoMallocThreadPool*   m_threadPool;
189
  bool                  m_isFinalPass;
190
  int                   m_filterPoc;
191
  Area                  m_area;
192
  int                   m_MCTFSpeedVal;
193
  Picture*              m_lastPicIn;
194
  bool                  m_lowResFltSearch = false;  // TODO: use this to select high/low-res filter (6/4 tap) for motion search
195
  bool                  m_lowResFltApply  = false;  // TODO: use this to select high/low-res filter (6/4 tap) for actual application
196
  int                   m_searchPttrn     = 0;
197
  int                   m_mctfUnitSize;
198
  FgaTemporalResidual   m_fgaResidual;      // grain measurement of the improved film grain analysis (--fga 2)
199
200
  void subsampleLuma    (const PelStorage &input, PelStorage &output, const int factor = 2) const;
201
202
  // refMargin is the width of the replicated border around the reference frame buffer.
203
  int motionErrorLuma   (const PelStorage &orig, const PelStorage &buffer, const int refMargin, const int x, const int y, int dx, int dy, const int bs, const int besterror) const;
204
205
  bool estimateLumaLn   ( std::atomic_int& blockX, std::atomic_int* prevLineX, Array2D<MotionVector> &mvs, const PelStorage &orig, const PelStorage &buffer, const int refMargin, const int blockSize,
206
    const Array2D<MotionVector> *previous, const int factor, const bool doubleRes, int blockY, int bitDepth ) const;
207
208
  void bilateralFilter  (const PelStorage &orgPic, std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo, PelStorage &newOrgPic, double overallStrength) const;
209
210
  void xFinalizeBlkLine (const PelStorage &orgPic, std::deque<TemporalFilterSourcePicInfo> &srcFrameInfo, PelStorage &newOrgPic, int yStart, const double sigmaSqCh[MAX_NUM_CH], double overallStrenght) const;
211
212
  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);
213
214
}; // END CLASS DEFINITION MCTF
215
216
//! \}
217
218
} // namespace vvenc
219
220