/work/vvenc/source/Lib/EncoderLib/CuTree.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 | | |
43 | | |
44 | | /** \file CuTree.h |
45 | | \brief look-ahead stage for CU-tree adaptive quantization |
46 | | */ |
47 | | |
48 | | #pragma once |
49 | | |
50 | | #include "CommonLib/CommonDef.h" |
51 | | #include "CommonLib/MCTF.h" |
52 | | #include "CommonLib/RdCost.h" |
53 | | #include "EncStage.h" |
54 | | |
55 | | #include <functional> |
56 | | #include <map> |
57 | | #include <memory> |
58 | | |
59 | | //! \ingroup EncoderLib |
60 | | //! \{ |
61 | | |
62 | | namespace vvenc { |
63 | | |
64 | | class NoMallocThreadPool; |
65 | | |
66 | | // Quantizer of the block coder, in the unnormalised N x N Hadamard domain (N times the orthonormal one): |
67 | | // level = ( |c| * scale + round ) >> 16, dequantised |c| = ( level * deqStep + 8 ) >> 4. |
68 | | struct TplQuant |
69 | | { |
70 | | int32_t scale; // 2^16 / step |
71 | | int32_t round; // dead-zone rounding offset, 2^16 units |
72 | | int32_t deqStep; // step, 2^4 units |
73 | | }; |
74 | | |
75 | | // The analysis works on half-resolution luma in N x N blocks, N = 8 or 16 (16x16 or 32x32 at full resolution, set |
76 | | // by vvenc_config::m_cuTreeBlockSize). The block kernels come in one version per size, indexed by TplBlkSize. |
77 | | enum TplBlkSize { TPL_BLK_8 = 0, TPL_BLK_16 = 1, NUM_TPL_BLK_SIZES = 2 }; |
78 | 0 | static constexpr int tplBlkSide( int sizeIdx ) { return 8 << sizeIdx; }Unexecuted instantiation: EncLib.cpp:vvenc::tplBlkSide(int) Unexecuted instantiation: CuTree.cpp:vvenc::tplBlkSide(int) |
79 | | |
80 | | // Codes the N x N residual org - pred: Hadamard transform, quantization, and when recon is given the inverse |
81 | | // transform added to pred. Returns the squared coefficient error in the unnormalised domain (N^2 times the error in |
82 | | // samples) and the estimated bits (Exp-Golomb length of each level plus sign and significance). |
83 | | typedef void ( *TplCodeBlockFn )( const Pel* org, ptrdiff_t orgStride, const Pel* pred, Pel* recon, ptrdiff_t reconStride, |
84 | | const TplQuant& quant, int maxVal, int64_t& dist, int& bits ); |
85 | | |
86 | | template<int N> |
87 | | void tplCodeBlockCore( const Pel* org, ptrdiff_t orgStride, const Pel* pred, Pel* recon, ptrdiff_t reconStride, |
88 | | const TplQuant& quant, int maxVal, int64_t& dist, int& bits ); |
89 | | |
90 | | // Bilinear prediction of an N x N block from the ( N + 1 )^2 reference samples at src, at the fractional position |
91 | | // ( fx, fy ) in 1/16 sample. |
92 | | typedef void ( *TplPredBlockFn )( const Pel* src, ptrdiff_t srcStride, int fx, int fy, Pel* dst ); |
93 | | |
94 | | template<int N> |
95 | | void tplPredBlockCore( const Pel* src, ptrdiff_t srcStride, int fx, int fy, Pel* dst ); |
96 | | |
97 | | // One row of 2x2 averages, ( a + b + c + d + 2 ) >> 2. |
98 | | typedef void ( *TplDownsampleRowFn )( const Pel* src, ptrdiff_t srcStride, Pel* dst, int dstWidth ); |
99 | | |
100 | | void tplDownsampleRowCore( const Pel* src, ptrdiff_t srcStride, Pel* dst, int dstWidth ); |
101 | | |
102 | | // ==================================================================================================================== |
103 | | // CU-tree adaptive quantization |
104 | | // |
105 | | // CU-tree (the macroblock-tree of x264, J. Garrett-Glaser 2009) lowers the QP of blocks that later pictures predict |
106 | | // from, so the bits spent on them improve every picture that copies them. This stage estimates that dependency |
107 | | // with the temporal dependency model (TPL) of J. Han, P. Wilkins, Y. Xu, J. Bankoski, "A quantitative approach to |
108 | | // the temporal dependency in video coding", arXiv:2108.11586, 2021, which libaom uses. MB-tree measures the |
109 | | // dependency on source samples, which overstates it where quantization removes the detail (film grain, low rates). |
110 | | // TPL codes every block at its picture's QP from both the original and a reconstructed reference; the extra |
111 | | // distortion and rate caused by the reference's coding error is what propagates. |
112 | | // |
113 | | // The analysis runs on half-resolution luma in 8x8 or 16x16 blocks (see TplBlkSize), in coding order. The stage |
114 | | // holds back the pictures of a GOP until the next GOP has arrived, because the GOP's key picture is also |
115 | | // referenced by the next one. The result is a QP offset per CTU, applied where QPA and the frame QP apply the |
116 | | // block importance mapping (BIM) offsets, which CU-tree replaces. |
117 | | // ==================================================================================================================== |
118 | | |
119 | | class CuTree : public EncStage |
120 | | { |
121 | | public: |
122 | | CuTree(); |
123 | | virtual ~CuTree(); |
124 | | |
125 | | void init( const VVEncCfg& encCfg, NoMallocThreadPool* threadPool ); |
126 | | |
127 | | // number of pictures the stage holds in addition to the encoder's own GOP queue |
128 | | static int getNumLookAheadPics( const VVEncCfg& encCfg ); |
129 | | |
130 | | TplCodeBlockFn m_codeBlock[NUM_TPL_BLK_SIZES]; // kernels per block size, SIMD where available |
131 | | TplPredBlockFn m_predBlock[NUM_TPL_BLK_SIZES]; |
132 | | TplDownsampleRowFn m_downsampleRow; |
133 | | |
134 | | #if defined( TARGET_SIMD_X86 ) && ENABLE_SIMD_OPT |
135 | | void initCuTree_X86(); |
136 | | template <X86_VEXT vext> |
137 | | void _initCuTree_X86(); |
138 | | #endif |
139 | | |
140 | | protected: |
141 | | virtual void initPicture ( Picture* pic ); |
142 | | virtual void processPictures( const PicList& picList, AccessUnitList& auList, PicList& doneList, PicList& freeList ); |
143 | | |
144 | | private: |
145 | | struct Frame; |
146 | | |
147 | | const VVEncCfg* m_encCfg; |
148 | | NoMallocThreadPool* m_threadPool; |
149 | | MCTF m_motionSearch; // provides the integer motion search of the coarsest level |
150 | | RdCost m_rdCost; // provides the SIMD Hadamard SATD |
151 | | FpDistFunc m_hadFunc; |
152 | | int m_lookAheadPics; |
153 | | int m_blkSizeIdx; // TplBlkSize of the analysis blocks |
154 | | int m_blkSize; // their side at half resolution |
155 | | int m_blkWidth; // width and height of the picture in analysis blocks |
156 | | int m_blkHeight; |
157 | | int m_qpBDOffset; |
158 | | double m_lambdaLeaf; // Lagrange multiplier at the QP of unreferenced pictures |
159 | | std::map<int, std::unique_ptr<Frame>> m_frames; // analysis data by POC, kept while it can still be referenced |
160 | | |
161 | | void xForEachRow ( int numRows, const std::function<void( int )>& fn ) const; |
162 | | void xDownsample ( const PelStorage& src, PelStorage& dst ) const; |
163 | | bool xIsBatchReady ( const PicList& picList, int& batchEndPoc ) const; |
164 | | Frame* xFindFrame ( int poc ) const; |
165 | | void xAnalyse ( Frame& frame, Picture* pic, bool flush ); |
166 | | void xEstimateMotion ( const Frame& cur, const Frame& ref, Array2D<MotionVector>& mvs ) const; |
167 | | void xSearchInteger ( const PelStorage& curPic, const PelStorage& refPic, const Array2D<MotionVector>& coarse, Array2D<MotionVector>& mvs ) const; |
168 | | void xSearchFractional ( const Frame& cur, const Frame& ref, const Array2D<MotionVector>& coarse, Array2D<MotionVector>& mvs ) const; |
169 | | void xPropagate ( int firstPoc ); |
170 | | void xDistribute ( Frame& ref, int bx, int by, const MotionVector& mv, double dist, double rate ) const; |
171 | | void xSetPicQpOffsets ( const std::vector<Picture*>& codingOrder, int batchEndPoc ); |
172 | | void xSetQpOffsets ( const Frame& frame, Picture* pic ) const; |
173 | | }; |
174 | | |
175 | | } // namespace vvenc |
176 | | |
177 | | //! \} |
178 | | |