/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 | | |