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