DecLib.h 17.8 KB
Newer Older
Alberto Gonzalez's avatar
Alberto Gonzalez committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
/* The copyright in this software is being made available under the BSD
 * License, included below. This software may be subject to other third party
 * and contributor rights, including patent rights, and no such rights are
 * granted under this license.
 *
 * Copyright (c) 2010-2023, ITU/ISO/IEC
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
 *    be used to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

/** \file     DecLib.h
    \brief    decoder class (header)
*/

#ifndef __DECLIB__
#define __DECLIB__

#include "DecSlice.h"
#include "CABACReader.h"
#include "VLCReader.h"
#include "SEIread.h"
#include "CacheModel.h"

#include "CommonLib/CommonDef.h"
#include "CommonLib/Picture.h"
#include "CommonLib/TrQuant.h"
#include "CommonLib/InterPrediction.h"
#include "CommonLib/IntraPrediction.h"
#include "CommonLib/DeblockingFilter.h"
#include "CommonLib/AdaptiveLoopFilter.h"
#include "CommonLib/SEI.h"
#include "CommonLib/Unit.h"
#include "CommonLib/Reshape.h"

class InputNALUnit;

//! \ingroup DecoderLib
//! \{

bool tryDecodePicture(Picture *pcPic, const int expectedPoc, const std::string &bitstreamFileName,
                      EnumArray<ParameterSetMap<APS>, ApsType> *apsMap = nullptr, bool bDecodeUntilPocFound = false,
                      int debugCTU = -1, int debugPOC = -1);
// Class definition
// ====================================================================================================================

/// decoder class
class DecLib
{
private:
  int                     m_maxRefPicNum;
  bool m_isFirstGeneralHrd;
  GeneralHrdParams        m_prevGeneralHrdParams;

  int                     m_prevGDRInSameLayerPOC[MAX_VPS_LAYERS]; ///< POC number of the latest GDR picture
  int                     m_prevGDRInSameLayerRecoveryPOC[MAX_VPS_LAYERS]; ///< Recovery POC number of the latest GDR picture
  NalUnitType             m_associatedIRAPType[MAX_VPS_LAYERS]; ///< NAL unit type of the previous IRAP picture
  int                     m_pocCRA[MAX_VPS_LAYERS];             ///< POC number of the previous CRA picture
  CheckCRAFlags           m_checkCRAFlags[MAX_VPS_LAYERS];
  int                     m_latestDRAPPOC;
  int                     m_latestEDRAPPOC;
  bool                    m_latestEDRAPIndicationLeadingPicturesDecodableFlag;
  int                     m_associatedIRAPDecodingOrderNumber[MAX_VPS_LAYERS]; ///< Decoding order number of the previous IRAP picture
  int                     m_decodingOrderCounter;
  int                     m_puCounter;
  bool                    m_seiInclusionFlag;
  int                     m_prevGDRSubpicPOC[MAX_VPS_LAYERS][MAX_NUM_SUB_PICS];
  int                     m_prevIRAPSubpicPOC[MAX_VPS_LAYERS][MAX_NUM_SUB_PICS];
  NalUnitType             m_prevIRAPSubpicType[MAX_VPS_LAYERS][MAX_NUM_SUB_PICS];
  int                     m_prevIRAPSubpicDecOrderNo[MAX_VPS_LAYERS][MAX_NUM_SUB_PICS];
  int                     m_pocRandomAccess;   ///< POC number of the random access point (the first IDR or CRA picture)
  int                     m_lastRasPoc;
  bool                    m_prevEOS[MAX_VPS_LAYERS];

  PicList                 m_cListPic;         //  Dynamic buffer
  ParameterSetManager     m_parameterSetManager;  // storage for parameter sets
  PicHeader               m_picHeader;            // picture header
  Slice*                  m_apcSlicePilot;


  SEIMessages             m_SEIs; ///< List of SEI messages that have been received before the first slice and between slices, excluding prefix SEIs...
  SEIScalabilityDimensionInfo* m_sdiSEIInFirstAU;
  SEIMultiviewAcquisitionInfo* m_maiSEIInFirstAU;
  SEIMultiviewViewPosition*    m_mvpSEIInFirstAU;

  // functional classes
  IntraPrediction         m_cIntraPred;
  InterPrediction         m_cInterPred;
  TrQuant                 m_cTrQuant;
  DecSlice                m_cSliceDecoder;
  TrQuant                 m_cTrQuantScalingList;
  DecCu                   m_cCuDecoder;
  HLSyntaxReader          m_HLSReader;
  CABACDecoder            m_CABACDecoder;
  SEIReader               m_seiReader;
#if JVET_S0257_DUMP_360SEI_MESSAGE
  SeiCfgFileDump          m_seiCfgDump;
#endif
  DeblockingFilter        m_deblockingFilter;
  SampleAdaptiveOffset    m_cSAO;
  AdaptiveLoopFilter      m_cALF;
  Reshape                 m_cReshaper;                        ///< reshaper class
  HRD                     m_HRD;
  // decoder side RD cost computation
  RdCost                  m_cRdCost;                      ///< RD cost computation class
#if JVET_J0090_MEMORY_BANDWITH_MEASURE
  CacheModel              m_cacheModel;
#endif
  bool isRandomAccessSkipPicture(int& iSkipFrame, int& iPOCLastDisplay, bool mixedNaluInPicFlag, uint32_t layerId);
  Picture*                m_pcPic;
  uint32_t                m_uiSliceSegmentIdx;
  uint32_t                m_prevLayerID;
  int                     m_prevPOC;
  int                     m_prevPicPOC;
  int                     m_prevTid0POC;
  bool                    m_bFirstSliceInPicture;
  bool                    m_firstPictureInSequence;
  SEIFilmGrainSynthesizer m_grainCharacteristic;
  PelStorage              m_grainBuf;
  SEIColourTransformApply m_colourTranfParams;
  PelStorage              m_invColourTransfBuf;
  bool                    m_firstSliceInSequence[MAX_VPS_LAYERS];
  bool                    m_firstSliceInBitstream;
  bool                    m_isFirstAuInCvs;
  bool                    m_accessUnitEos[MAX_VPS_LAYERS];
  bool                    m_prevSliceSkipped;
  int                     m_skippedPOC;
  uint32_t                m_skippedLayerID;
  int                     m_lastPOCNoOutputPriorPics;
  bool                    m_isNoOutputPriorPics;
  bool                    m_lastNoOutputBeforeRecoveryFlag[MAX_VPS_LAYERS];    //value of variable NoOutputBeforeRecoveryFlag of the assocated CRA/GDR pic
  int                     m_sliceLmcsApsId;         //value of LmcsApsId, constraint is same id for all slices in one picture
  std::ostream           *m_pDecodedSEIOutputStream;
  uint32_t                m_audIrapOrGdrAuFlag;
#if JVET_S0257_DUMP_360SEI_MESSAGE
  std::string             m_decoded360SeiDumpFileName;
#endif

  int                     m_decodedPictureHashSEIEnabled;  ///< Checksum(3)/CRC(2)/MD5(1)/disable(0) acting on decoded picture hash SEI message
  uint32_t                m_numberOfChecksumErrorsDetected;

  bool                    m_warningMessageSkipPicture;

  std::list<InputNALUnit*> m_prefixSEINALUs; /// Buffered up prefix SEI NAL Units.
#if JVET_Z0120_SII_SEI_PROCESSING
  bool                                m_ShutterFilterEnable;          ///< enable Post-processing with Shutter Interval SEI
#endif
  int                     m_debugPOC;
  int                     m_debugCTU;

  struct AccessUnitInfo
  {
    NalUnitType     m_nalUnitType; ///< nal_unit_type
    uint32_t        m_temporalId;  ///< temporal_id
    uint32_t        m_nuhLayerId;  ///< nuh_layer_id
  };
  std::vector<AccessUnitInfo> m_accessUnitNals;
  struct AccessUnitPicInfo
  {
    NalUnitType     m_nalUnitType; ///< nal_unit_type
    uint32_t        m_temporalId;  ///< temporal_id
    uint32_t        m_nuhLayerId;  ///< nuh_layer_id
    int             m_POC;
  };
  std::vector<AccessUnitPicInfo> m_accessUnitPicInfo;
  std::vector<AccessUnitPicInfo> m_firstAccessUnitPicInfo;
  struct AccessUnitNestedSliSeiInfo
  {
    bool m_nestedSliPresent;
    uint32_t m_numOlssNestedSli;
    uint32_t m_olsIdxNestedSLI[MAX_NUM_OLSS];
  };
  std::vector<AccessUnitNestedSliSeiInfo> m_accessUnitNestedSliSeiInfo;
  int m_accessUnitSpsNumSubpic[MAX_VPS_LAYERS];
  struct NalUnitInfo
  {
    NalUnitType     m_nalUnitType; ///< nal_unit_type
    uint32_t        m_nuhLayerId;  ///< nuh_layer_id
    uint32_t        m_firstCTUinSlice; /// the first CTU in slice, specified with raster scan order ctu address
    int             m_POC;             /// the picture order
  };
  std::vector<NalUnitInfo> m_nalUnitInfo[MAX_VPS_LAYERS];
  EnumArray<std::vector<int>, ApsType> m_accessUnitApsNals;
  std::vector<int> m_accessUnitSeiTids;
  std::vector<bool> m_accessUnitNoOutputPriorPicFlags;

  // NAL unit type, layer ID, and SEI payloadType
  std::vector<std::tuple<NalUnitType, int, SEI::PayloadType>> m_accessUnitSeiPayLoadTypes;

  std::vector<NalUnitType> m_pictureUnitNals;
  std::list<InputNALUnit *> m_pictureSeiNalus;
  std::list<InputNALUnit *> m_suffixApsNalus;
  std::list<InputNALUnit*> m_accessUnitSeiNalus;

  OPI*                    m_opi;
  bool                    m_mTidExternalSet;
  bool                    m_mTidOpiSet;
  bool                    m_tOlsIdxTidExternalSet;
  bool                    m_tOlsIdxTidOpiSet;
  VPS*                    m_vps;
  int                     m_maxDecSubPicIdx;
  int                     m_maxDecSliceAddrInSubPic;
  int                     m_clsVPSid;

#if GDR_ENABLED
  int m_lastGdrPoc;
  int m_lastGdrRecoveryPocCnt;
#endif

public:
  int                     m_targetSubPicIdx;

  DCI*                    m_dci;
  EnumArray<ParameterSetMap<APS>, ApsType> *m_apsMapEnc = nullptr;
#if GDR_LEAK_TEST
public:
  int                     m_gdrPocRandomAccess;
#endif // GDR_LEAK_TEST

public:
  DecLib();
  virtual ~DecLib();

  void  create  ();
  void  destroy ();

  void  setDecodedPictureHashSEIEnabled(int enabled) { m_decodedPictureHashSEIEnabled=enabled; }

  void  init(
#if JVET_J0090_MEMORY_BANDWITH_MEASURE
    const std::string& cacheCfgFileName
#endif
  );
  bool  decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay, int iTargetOlsIdx);
  void  deletePicBuffer();

  void  executeLoopFilters();
  void finishPicture(int &poc, PicList *&rpcListPic, MsgLevel msgl = INFO, bool associatedWithNewClvs = false);
  void  finishPictureLight(int& poc, PicList*& rpcListPic );
  void  checkNoOutputPriorPics (PicList* rpcListPic);
  void  checkNalUnitConstraints( uint32_t naluType );
  void  checkPicTypeAfterEos();
  void  updateAssociatedIRAP();
  void  updatePrevGDRInSameLayer();
  void  updatePrevIRAPAndGDRSubpic();
  bool  getGDRRecoveryPocReached()          { return ( m_pcPic->getPOC() >= m_prevGDRInSameLayerRecoveryPOC[m_pcPic->layerId] ); }

  bool  getNoOutputPriorPicsFlag () const   { return m_isNoOutputPriorPics; }
  void  setNoOutputPriorPicsFlag (bool val) { m_isNoOutputPriorPics = val; }
  void  setFirstSliceInPicture (bool val)  { m_bFirstSliceInPicture = val; }
  bool  getFirstSliceInPicture () const  { return m_bFirstSliceInPicture; }
  bool  getFirstSliceInSequence(int layerId) const { return m_firstSliceInSequence[layerId]; }
  void  setFirstSliceInSequence(bool val, int layerId) { m_firstSliceInSequence[layerId] = val; }
  void  setDecodedSEIMessageOutputStream(std::ostream *pOpStream) { m_pDecodedSEIOutputStream = pOpStream; }
#if JVET_S0257_DUMP_360SEI_MESSAGE
  void  setDecoded360SEIMessageFileName(std::string &Dump360SeiFileName) { m_decoded360SeiDumpFileName = Dump360SeiFileName; }
#endif
  uint32_t  getNumberOfChecksumErrorsDetected() const { return m_numberOfChecksumErrorsDetected; }

#if GDR_ENABLED
  void setLastGdrPoc(int poc) { m_lastGdrPoc = poc;  }
  int  getLastGdrPoc()        { return m_lastGdrPoc; }
  void setLastGdrRecoveryPocCnt(int recoveryPocCnt) { m_lastGdrRecoveryPocCnt = recoveryPocCnt; }
  int  getLastGdrRecoveryPocCnt()                     { return m_lastGdrRecoveryPocCnt; }
#endif

  int  getDebugCTU( )               const { return m_debugCTU; }
  void setDebugCTU( int debugCTU )        { m_debugCTU = debugCTU; }
  int  getDebugPOC( )               const { return m_debugPOC; };
  void setDebugPOC( int debugPOC )        { m_debugPOC = debugPOC; };
  void resetAccessUnitNals()              { m_accessUnitNals.clear();    }
  void resetAccessUnitPicInfo()           { m_accessUnitPicInfo.clear(); }
  void resetAccessUnitApsNals()
  {
    for (auto &nals: m_accessUnitApsNals)
    {
      nals.clear();
    }
  }
  void resetAccessUnitSeiTids()           { m_accessUnitSeiTids.clear(); }
  void resetAudIrapOrGdrAuFlag()          { m_audIrapOrGdrAuFlag = false; }
  void resetAccessUnitEos()               { memset(m_accessUnitEos, false, sizeof(m_accessUnitEos)); }
  void checkTidLayerIdInAccessUnit();
  void resetAccessUnitSeiPayLoadTypes()   { m_accessUnitSeiPayLoadTypes.clear(); }
  void checkSEIInAccessUnit();
  void checkSeiContentInAccessUnit();
  void resetAccessUnitSeiNalus();
  void checkLayerIdIncludedInCvss();
  void CheckNoOutputPriorPicFlagsInAccessUnit();
  void resetAccessUnitNoOutputPriorPicFlags() { m_accessUnitNoOutputPriorPicFlags.clear(); }
  void checkMultiSubpicNum(int olsIdx);
  void resetAccessUnitNestedSliSeiInfo()  { m_accessUnitNestedSliSeiInfo.clear(); }
  void resetIsFirstAuInCvs();
  void checkSeiInPictureUnit();
  void resetPictureSeiNalus();
  void resetPrefixSeiNalus();
  bool isSliceNaluFirstInAU( bool newPicture, InputNALUnit &nalu );
  void processSuffixApsNalus();

  void checkAPSInPictureUnit();
  void resetPictureUnitNals() { m_pictureUnitNals.clear(); }

  const VPS* getVPS()                     { return m_vps; }
  void deriveTargetOutputLayerSet( const int targetOlsIdx ) { if( m_vps != nullptr ) m_vps->deriveTargetOutputLayerSet( targetOlsIdx ); }

  void  initScalingList()
  {
    m_cTrQuantScalingList.init(nullptr, MAX_TB_SIZEY, false, false, false, false);
  }

  void  setAPSMapEnc(EnumArray<ParameterSetMap<APS>, ApsType> *apsMap) { m_apsMapEnc = apsMap; }
  bool  isNewPicture( std::ifstream *bitstreamFile, class InputByteStream *bytestream );
  bool  isNewAccessUnit( bool newPicture, std::ifstream *bitstreamFile, class InputByteStream *bytestream );

  bool      getHTidExternalSetFlag()               const { return m_mTidExternalSet; }
  void      setHTidExternalSetFlag(bool mTidExternalSet)  { m_mTidExternalSet = mTidExternalSet; }
  bool      getHTidOpiSetFlag()               const { return m_mTidOpiSet; }
  void      setHTidOpiSetFlag(bool mTidOpiSet)  { m_mTidOpiSet = mTidOpiSet; }
  bool      getTOlsIdxExternalFlag()               const { return m_tOlsIdxTidExternalSet; }
  void      setTOlsIdxExternalFlag (bool tOlsIdxExternalSet)  { m_tOlsIdxTidExternalSet = tOlsIdxExternalSet; }
  bool      getTOlsIdxOpiFlag()               const { return m_tOlsIdxTidOpiSet; }
  void      setTOlsIdxOpiFlag(bool tOlsIdxOpiSet)  { m_tOlsIdxTidOpiSet = tOlsIdxOpiSet; }
  const OPI* getOPI()                     { return m_opi; }

  bool      getMixedNaluTypesInPicFlag();
#if GREEN_METADATA_SEI_ENABLED
  FeatureCounterStruct m_featureCounter;
  bool m_GMFAFramewise;
  std::string   m_GMFAFile;
  void setFeatureCounter (FeatureCounterStruct b ) {m_featureCounter = b;}
  FeatureCounterStruct getFeatureCounter (){return m_featureCounter;}
  void setGMFAFile(std::string b){m_GMFAFile = b;}
  void setFeatureAnalysisFramewise(bool b){m_GMFAFramewise = b;}
#endif

#if JVET_Z0120_SII_SEI_PROCESSING
  bool  getShutterFilterFlag()        const { return m_ShutterFilterEnable; }
  void  setShutterFilterFlag(bool value) { m_ShutterFilterEnable = value; }
#endif


protected:
  void  xUpdateRasInit(Slice* slice);

  Picture * xGetNewPicBuffer( const SPS &sps, const PPS &pps, const uint32_t temporalLayer, const int layerId );
  void  xCreateLostPicture( int iLostPOC, const int layerId );
  void  xCreateUnavailablePicture( const PPS *pps, const int iUnavailablePoc, const bool longTermFlag, const int temporalId, const int layerId, const bool interLayerRefPicFlag );
  void  checkParameterSetsInclusionSEIconstraints(const InputNALUnit nalu);
  void  xActivateParameterSets( const InputNALUnit nalu );
  void  xCheckParameterSetConstraints( const int layerId );
  void      xDecodePicHeader( InputNALUnit& nalu );
  bool      xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDisplay);
  void      xDecodeOPI( InputNALUnit& nalu );
  void      xDecodeVPS( InputNALUnit& nalu );
  void      xDecodeDCI( InputNALUnit& nalu );
  void      xDecodeSPS( InputNALUnit& nalu );
  void      xDecodePPS( InputNALUnit& nalu );
  void      xDecodeAPS(InputNALUnit& nalu);
  void      xUpdatePreviousTid0POC(Slice *pSlice)
  {
    if( (pSlice->getTLayer() == 0) && (pSlice->getNalUnitType() != NAL_UNIT_CODED_SLICE_RASL) && (pSlice->getNalUnitType() != NAL_UNIT_CODED_SLICE_RADL) && !pSlice->getPicHeader()->getNonReferencePictureFlag() )
    {
      m_prevTid0POC = pSlice->getPOC();
    }
  }
  void      xParsePrefixSEImessages();
  void      xParsePrefixSEIsForUnknownVCLNal();
  void      xCheckPrefixSEIMessages( SEIMessages& prefixSEIs );
  void      xCheckDUISEIMessages(SEIMessages &prefixSEIs);


  void  xCheckNalUnitConstraintFlags( const ConstraintInfo *cInfo, uint32_t naluType );
  void     xCheckMixedNalUnit(Slice* pcSlice, SPS *sps, InputNALUnit &nalu);
};// END CLASS DEFINITION DecLib


//! \}

#endif // __DECTOP__