Coverage Report

Created: 2026-10-28 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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