/work/vvenc/source/Lib/EncoderLib/EncGOP.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 EncGOP.h |
43 | | \brief GOP encoder class (header) |
44 | | */ |
45 | | |
46 | | #pragma once |
47 | | |
48 | | #include "EncSampleAdaptiveOffset.h" |
49 | | #include "VLCWriter.h" |
50 | | #include "SEIwrite.h" |
51 | | #include "SEIEncoder.h" |
52 | | #include "Analyze.h" |
53 | | #include "EncPicture.h" |
54 | | #include "CommonLib/Picture.h" |
55 | | #include "CommonLib/CommonDef.h" |
56 | | #include "CommonLib/Nal.h" |
57 | | #include "EncHRD.h" |
58 | | |
59 | | #include <map> |
60 | | #include <set> |
61 | | #include "EncStage.h" |
62 | | #include "SEIFilmGrainAnalyzer.h" |
63 | | |
64 | | #include <vector> |
65 | | #include <list> |
66 | | #include <stdlib.h> |
67 | | #include <atomic> |
68 | | |
69 | | |
70 | | #include "Utilities/NoMallocThreadPool.h" |
71 | | #include <mutex> |
72 | | #include <condition_variable> |
73 | | |
74 | | //! \ingroup EncoderLib |
75 | | //! \{ |
76 | | |
77 | | namespace vvenc { |
78 | | |
79 | | // ==================================================================================================================== |
80 | | |
81 | | class InputByteStream; |
82 | | class DecLib; |
83 | | class EncHRD; |
84 | | class MsgLog; |
85 | | class GOPCfg; |
86 | | |
87 | | // ==================================================================================================================== |
88 | | |
89 | | class EncGOP; |
90 | | struct FinishTaskParam { |
91 | | EncGOP* gopEncoder; |
92 | | EncPicture* picEncoder; |
93 | | Picture* pic; |
94 | 0 | FinishTaskParam() : gopEncoder( nullptr ), picEncoder( nullptr ), pic( nullptr ) {} |
95 | 1.49k | FinishTaskParam( EncGOP* _g, EncPicture* _e, Picture* _p ) : gopEncoder( _g ), picEncoder( _e ), pic( _p ) {} |
96 | | }; |
97 | | |
98 | | // ==================================================================================================================== |
99 | | struct RateCapParam { |
100 | | unsigned accumActualBits = 0; |
101 | | unsigned accumTargetBits = 0; |
102 | | unsigned accumGopCounter = 0; |
103 | | double nonRateCapEstim = 0.0; |
104 | | int gopAdaptedQPAdj = 0; |
105 | | |
106 | | void reset() |
107 | 1.49k | { |
108 | 1.49k | accumActualBits = 0; |
109 | 1.49k | accumTargetBits = 0; |
110 | 1.49k | accumGopCounter = 0; |
111 | 1.49k | } |
112 | | }; |
113 | | |
114 | | // ==================================================================================================================== |
115 | | // film grain parameters estimated by the film grain analysis, as signalled in the FGC SEI |
116 | | struct FilmGrainParam { |
117 | | int log2ScaleFactor = 0; |
118 | | SeiFgc::CompModel compModel[ MAX_NUM_COMP ]; |
119 | | |
120 | 0 | FilmGrainParam() = default; |
121 | | // The parameters of the analysis, with the grain strength set to strength percent of the analysed grain. |
122 | | FilmGrainParam( const FGAnalyzer& fgAnalyzer, double strength ) |
123 | 0 | { |
124 | 0 | fgAnalyzer.getSignalledParameters( strength, log2ScaleFactor, compModel ); |
125 | 0 | for( auto& cm : compModel ) |
126 | 0 | { |
127 | | // only the signalled intervals and model values, as the SEI writer expects |
128 | 0 | cm.intensityValues.resize( cm.numIntensityIntervals ); |
129 | 0 | for( auto& iv : cm.intensityValues ) |
130 | 0 | { |
131 | 0 | iv.compModelValue.resize( cm.numModelValues ); |
132 | 0 | } |
133 | 0 | } |
134 | 0 | } |
135 | | }; |
136 | | |
137 | | class EncGOP : public EncStage |
138 | | { |
139 | | private: |
140 | | MsgLog& msg; |
141 | | |
142 | | Analyze m_AnalyzeAll; |
143 | | Analyze m_AnalyzeI; |
144 | | Analyze m_AnalyzeP; |
145 | | Analyze m_AnalyzeB; |
146 | | |
147 | | std::function<void( void*, vvencYUVBuffer* )> m_recYuvBufFunc; |
148 | | void* m_recYuvBufCtx; |
149 | | |
150 | | NoMallocThreadPool* m_threadPool; |
151 | | std::mutex m_gopEncMutex; |
152 | | std::condition_variable m_gopEncCond; |
153 | | XUCache m_shrdUnitCache; |
154 | | std::mutex m_unitCacheMutex; |
155 | | |
156 | | const VVEncCfg* m_pcEncCfg; |
157 | | const GOPCfg* m_gopCfg; |
158 | | RateCtrl* m_pcRateCtrl; |
159 | | HLSWriter m_HLSWriter; |
160 | | SEIWriter m_seiWriter; |
161 | | SEIEncoder m_seiEncoder; |
162 | | BlkStat m_BlkStat; |
163 | | |
164 | | ParameterSetMap<SPS> m_spsMap; |
165 | | ParameterSetMap<PPS> m_ppsMap; |
166 | | EncHRD m_EncHRD; |
167 | | VPS m_VPS; |
168 | | DCI m_DCI; |
169 | | |
170 | | bool m_isPreAnalysis; |
171 | | bool m_bFirstWrite; |
172 | | bool m_bRefreshPending; |
173 | | int m_lastCodingNum; |
174 | | int m_numPicsCoded; |
175 | | int m_numPicsInMissing; |
176 | | int m_numPicsOutOffset; |
177 | | uint64_t m_lastCts; |
178 | | int m_pocRecOut; |
179 | | int m_ticksPerFrameMul4; |
180 | | int m_lastIDR; |
181 | | int m_lastRasPoc; |
182 | | int m_pocCRA; |
183 | | int m_associatedIRAPPOC; |
184 | | vvencNalUnitType m_associatedIRAPType; |
185 | | RateCapParam m_rcap; |
186 | | |
187 | | ThreadRsrcPool m_threadRsrc; ///< CU encoders of the worker threads, shared by all picture encoders |
188 | | std::list<EncPicture*> m_freePicEncoderList; |
189 | | std::list<Picture*> m_gopEncListInput; |
190 | | std::list<Picture*> m_gopEncListOutput; |
191 | | std::list<Picture*> m_procList; |
192 | | std::list<Picture*> m_rcUpdateList; |
193 | | std::list<Picture*> m_rcInputReorderList; // used in RC in IFP lines synchro mode |
194 | | std::deque<PicApsGlobal*> m_globalApsList; |
195 | | std::vector<int> m_globalCtuQpVector; |
196 | | bool m_forceSCC; |
197 | | |
198 | | FGAnalyzer m_fgAnalyzer; ///< film grain analysis (--fga) |
199 | | |
200 | | // An analysis, run as a thread pool task. The tasks run one after the other in coding order (each waits |
201 | | // for the previous one), because every analysis adds to the statistics of the previous ones. |
202 | | struct FgaTask |
203 | | { |
204 | | EncGOP* gop = nullptr; |
205 | | Picture* pic = nullptr; |
206 | | int codingNum = 0; |
207 | | int startPoc = std::numeric_limits<int>::min(); ///< the first picture in output order its result applies to |
208 | | bool sceneCut = false; ///< a scene cut lies between the previously analysed picture and this one |
209 | | FilmGrainParam result; |
210 | | WaitCounter counter; |
211 | | }; |
212 | | std::deque<std::unique_ptr<FgaTask>> m_fgaTasks; ///< analyses whose access unit is not written yet |
213 | | std::unique_ptr<FgaTask> m_fgaConsumed; ///< the last consumed task, kept until the next one has run |
214 | | FgaTask* m_fgaLast = nullptr; ///< the last submitted task |
215 | | int m_fgaPrevAnalysedPoc = std::numeric_limits<int>::min(); ///< POC of the last analysed picture |
216 | | // The film grain parameter sets by the POC from which they apply in output order: an analysis applies from the |
217 | | // picture after the previously analysed one, or from a scene cut between them. The latest few are kept. |
218 | | static constexpr size_t FGC_PARAM_SETS = 8; |
219 | | std::map<int, FilmGrainParam> m_fgcByStartPoc; |
220 | | bool m_fgcCompSignalled[ MAX_NUM_COMP ] = { false, false, false }; ///< components present in a parameter set so far |
221 | | // The POCs of the latest access units written in the current coded layer video sequence (more than two GOPs), and |
222 | | // whether a RASL picture carried a film grain SEI since the last other picture; to decide where the SEI is needed. |
223 | | static constexpr size_t FGC_SEI_HISTORY = 160; |
224 | | std::set<int> m_fgcWrittenPocs; |
225 | | bool m_fgcRaslSeiPending = false; |
226 | | |
227 | | public: |
228 | | EncGOP( MsgLog& msglog ); |
229 | | virtual ~EncGOP(); |
230 | | |
231 | | void setRecYUVBufferCallback( void* ctx, std::function<void( void*, vvencYUVBuffer* )> func ); |
232 | | |
233 | | void init ( const VVEncCfg& encCfg, const GOPCfg* gopCfg, RateCtrl& rateCtrl, NoMallocThreadPool* threadPool, bool isPreAnalysis ); |
234 | | void printOutSummary ( const bool printMSEBasedSNR, const bool printSequenceMSE, const bool printHexPsnr ); |
235 | | void getParameterSets ( AccessUnitList& accessUnit ); |
236 | | |
237 | | protected: |
238 | | virtual void initPicture ( Picture* pic ); |
239 | | virtual void processPictures( const PicList& picList, AccessUnitList& auList, PicList& doneList, PicList& freeList ); |
240 | | virtual void waitForFreeEncoders(); |
241 | | |
242 | | private: |
243 | | void xUpdateRasInit ( Slice* slice ); |
244 | | void xProcessPictures ( AccessUnitList& auList, PicList& doneList ); |
245 | | void xEncodePicture ( Picture* pic, EncPicture* picEncoder ); |
246 | | void xOutputRecYuv ( const PicList& picList ); |
247 | | void xReleasePictures ( const PicList& picList, PicList& freeList ); |
248 | | |
249 | | void xInitVPS ( VPS &vps ) const; |
250 | | void xInitDCI ( DCI &dci, const SPS &sps, const int dciId ) const; |
251 | | void xInitConstraintInfo ( ConstraintInfo &ci ) const; |
252 | | void xInitSPS ( SPS &sps ) const; |
253 | | void xInitPPS ( PPS &pps, const SPS &sps ) const; |
254 | | void xInitPPSforTiles ( PPS &pps, const SPS &sps ) const; |
255 | | void xInitRPL ( SPS &sps ) const; |
256 | | void xInitHrdParameters ( SPS &sps ); |
257 | | |
258 | | vvencNalUnitType xGetNalUnitType ( const GOPEntry* _gopEntry ) const; |
259 | | bool xIsSliceTemporalSwitchingPoint ( const Slice* slice, const PicList& picList ) const; |
260 | | |
261 | | void xSetupPicAps ( Picture* pic ); |
262 | | void xAnalyzeFilmGrain ( Picture& pic ); |
263 | | void xRunFgaTask ( FgaTask& task ); |
264 | | void xWaitFgaTasks (); |
265 | | void xInitPicsInCodingOrder ( const PicList& picList ); |
266 | | void xGetProcessingLists ( std::list<Picture*>& procList, std::list<Picture*>& rcUpdateList, const bool lockStepMode ); |
267 | | void xUpdateVAStartOfLastGop ( Picture& keyPic ) const; |
268 | | void xInitGopQpCascade ( Picture& keyPic, PicList::const_iterator picItr, const PicList& picList ); |
269 | | void xInitFirstSlice ( Picture& pic, const PicList& picList, bool isEncodeLtRef ); |
270 | | void xInitSliceTMVPFlag ( PicHeader* picHeader, const Slice* slice ); |
271 | | void xUpdateRPRtmvp ( PicHeader* picHeader, Slice* slice ); |
272 | | void xInitSliceMvdL1Zero ( PicHeader* picHeader, const Slice* slice ); |
273 | | void xSelectReferencePictureList ( Slice* slice ) const; |
274 | | void xSyncAlfAps ( Picture& pic ); |
275 | | |
276 | | void xUpdateRcIfp (); |
277 | | void xWritePicture ( Picture& pic, AccessUnitList& au, bool isEncodeLtRef ); |
278 | | int xWriteParameterSets ( Picture& pic, AccessUnitList& accessUnit, HLSWriter& hlsWriter ); |
279 | | int xWritePictureSlices ( Picture& pic, AccessUnitList& accessUnit, HLSWriter& hlsWriter ); |
280 | | void xAddFilmGrainParameters ( const FgaTask& task ); |
281 | | const FilmGrainParam& xFilmGrainParametersAt( int poc ) const; |
282 | | SeiFgc xFilmGrainSei ( const FilmGrainParam& param, ChromaFormat chromaFormat ); |
283 | | bool xFilmGrainSeiNeeded ( const Slice& slice, const SeiFgc& sei, ChromaFormat chromaFormat ); |
284 | | void xWriteLeadingSEIs ( const Picture& pic, AccessUnitList& accessUnit ); |
285 | | void xWriteTrailingSEIs ( const Picture& pic, AccessUnitList& accessUnit, std::string& digestStr ); |
286 | | int xWriteVPS ( AccessUnitList &accessUnit, const VPS *vps, HLSWriter& hlsWriter ); |
287 | | int xWriteDCI ( AccessUnitList &accessUnit, const DCI *dci, HLSWriter& hlsWriter ); |
288 | | int xWriteSPS ( AccessUnitList &accessUnit, const SPS *sps, HLSWriter& hlsWriter ); |
289 | | int xWritePPS ( AccessUnitList &accessUnit, const PPS *pps, const SPS *sps, HLSWriter& hlsWriter ); |
290 | | int xWriteAPS ( AccessUnitList &accessUnit, const APS *aps, HLSWriter& hlsWriter, vvencNalUnitType eNalUnitType ); |
291 | | void xWriteAccessUnitDelimiter ( AccessUnitList &accessUnit, Slice* slice, bool IrapOrGdr, HLSWriter& hlsWriter ); |
292 | | void xWriteSEI ( vvencNalUnitType naluType, SEIMessages& seiMessages, AccessUnitList &accessUnit, AccessUnitList::iterator &auPos, int temporalId, const SPS *sps ); |
293 | | void xWriteSEISeparately ( vvencNalUnitType naluType, SEIMessages& seiMessages, AccessUnitList &accessUnit, AccessUnitList::iterator &auPos, int temporalId, const SPS *sps ); |
294 | | void xAttachSliceDataToNalUnit ( OutputNALUnit& rNalu, const OutputBitstream* pcBitstreamRedirect ); |
295 | | void xCabacZeroWordPadding ( const Picture& pic, const Slice* slice, uint32_t binCountsInNalUnits, uint32_t numBytesInVclNalUnits, std::ostringstream &nalUnitData ); |
296 | | |
297 | | void xUpdateRateCap(); |
298 | | void xUpdateRateCapBits ( const Picture* pic, const uint32_t uibits ); |
299 | | void xAddPSNRStats( const Picture* pic, CPelUnitBuf cPicD, AccessUnitList&, bool printFrameMSE, double* PSNR_Y, bool isEncodeLtRef ); |
300 | | uint64_t xFindDistortionPlane ( const CPelBuf& pic0, const CPelBuf& pic1, uint32_t rshift ) const; |
301 | | void xPrintPictureInfo ( const Picture& pic, AccessUnitList& accessUnit, const std::string& digestStr, bool printFrameMSE, bool isEncodeLtRef ); |
302 | 1.49k | inline bool xEncodersFinished () { return ( int ) m_freePicEncoderList.size() >= std::max(1, m_pcEncCfg->m_maxParallelFrames); } |
303 | | inline bool xLockStepPicsFinished () |
304 | 0 | { |
305 | 0 | std::lock_guard<std::mutex> lock( m_gopEncMutex ); |
306 | 0 | return ( int ) m_freePicEncoderList.size() >= std::max(1, m_pcEncCfg->m_maxParallelFrames); |
307 | 0 | } |
308 | | void xForceScc ( Picture& pic ); |
309 | | |
310 | | };// END CLASS DEFINITION EncGOP |
311 | | |
312 | | } // namespace vvenc |
313 | | |
314 | | //! \} |
315 | | |