diff --git a/doc/software-manual.tex b/doc/software-manual.tex index a74311fde631c0f6b3ea67131e91670ea0b3f60c..79bed41558a6f7099bba441060c7663fffbd06ec 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -1965,6 +1965,11 @@ beginning of each line of CTBs in order to produce a bitstream that can be encoded or decoded using one or more cores. \\ +\Option{WaveFrontEntryPointsPresent} & +%\ShortOption{\None} & +\Default{false} & +Allow signalling of entry points for WPP in slice header. +\\ \end{OptionTableNoShorthand} diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 3fa5065a9ae66b35ba2365657c20b9e6b981412e..6efcb035b5c8e16721400d03625fd82687d3d567 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -747,6 +747,9 @@ void EncApp::xInitLibCfg() m_cEncLib.setCcvSEIMaxLuminanceValue (m_ccvSEIMaxLuminanceValue); m_cEncLib.setCcvSEIAvgLuminanceValue (m_ccvSEIAvgLuminanceValue); m_cEncLib.setEntropyCodingSyncEnabledFlag ( m_entropyCodingSyncEnabledFlag ); +#if JVET_Q0151_Q0205_ENTRYPOINTS + m_cEncLib.setEntropyCodingSyncEntryPointPresentFlag ( m_entropyCodingSyncEntryPointPresentFlag ); +#endif m_cEncLib.setTMVPModeId ( m_TMVPModeId ); m_cEncLib.setSliceLevelRpl ( m_sliceLevelRpl ); m_cEncLib.setSliceLevelDblk ( m_sliceLevelDblk ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 929dcd0b5dd673f8f7699197b4591185a7e358d7..dc7b5a3d1572db6e361bc6000b35d45d43c8e758 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1188,6 +1188,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("Log2ParallelMergeLevel", m_log2ParallelMergeLevel, 2u, "Parallel merge estimation region") #endif ("WaveFrontSynchro", m_entropyCodingSyncEnabledFlag, false, "0: entropy coding sync disabled; 1 entropy coding sync enabled") +#if JVET_Q0151_Q0205_ENTRYPOINTS + ("WaveFrontEntryPointsPresent", m_entropyCodingSyncEntryPointPresentFlag, false, "0: entry points for WPP is not present; 1 entry points for WPP may be present in slice header") +#endif ("ScalingList", m_useScalingListId, SCALING_LIST_OFF, "0/off: no scaling list, 1/default: default scaling lists, 2/file: scaling lists specified in ScalingListFile") ("ScalingListFile", m_scalingListFileName, string(""), "Scaling list file name. Use an empty string to produce help.") ("DisableScalingMatrixForLFNST", m_disableScalingMatrixForLfnstBlks, true, "Disable scaling matrices, when enabled, for LFNST-coded blocks") @@ -1739,6 +1742,13 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) m_outputBitDepth [CHANNEL_TYPE_CHROMA] = m_outputBitDepth [CHANNEL_TYPE_LUMA ]; } +#if JVET_Q0151_Q0205_ENTRYPOINTS + if( !m_entropyCodingSyncEnabledFlag ) + { + m_entropyCodingSyncEntryPointPresentFlag = false; + } +#endif + m_InputChromaFormatIDC = numberToChromaFormat(tmpInputChromaFormat); m_chromaFormatIDC = ((tmpChromaFormat == 0) ? (m_InputChromaFormatIDC) : (numberToChromaFormat(tmpChromaFormat))); #if EXTENSION_360_VIDEO diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 198a5bc67a08df9db5e868fb9127d383c69e66a6..e6c8ee61f90df63d37780a05f157ecbf62da3958 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -488,7 +488,9 @@ protected: bool m_subPicPartitionFlag; bool m_singleSlicePerSubPicFlag; bool m_entropyCodingSyncEnabledFlag; - +#if JVET_Q0151_Q0205_ENTRYPOINTS + bool m_entropyCodingSyncEntryPointPresentFlag; ///< flag for the presence of entry points for WPP +#endif bool m_bFastUDIUseMPMEnabled; bool m_bFastMEForGenBLowDelayEnabled; diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp index 3246480c9c5bbb28f946820137c7b809765db88d..88f82c69430d78dd240fccfc9fb3fe57641a26dc 100644 --- a/source/Lib/CommonLib/CodingStructure.cpp +++ b/source/Lib/CommonLib/CodingStructure.cpp @@ -1536,7 +1536,11 @@ const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const C const CodingUnit* cu = getCU( pos, _chType ); // exists same slice and tile cu precedes curCu in encoding order // (thus, is either from parent CS in RD-search or its index is lower) +#if JVET_Q0151_Q0205_ENTRYPOINTS + const bool wavefrontsEnabled = curCu.slice->getSPS()->getEntropyCodingSyncEnabledFlag(); +#else const bool wavefrontsEnabled = curCu.slice->getPPS()->getEntropyCodingSyncEnabledFlag(); +#endif int ctuSizeBit = floorLog2(curCu.cs->sps->getMaxCUWidth()); int xNbY = pos.x << getChannelTypeScaleX( _chType, curCu.chromaFormat ); int xCurr = curCu.blocks[_chType].x << getChannelTypeScaleX( _chType, curCu.chromaFormat ); @@ -1554,7 +1558,11 @@ const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const C const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const Position curPos, const unsigned curSliceIdx, const unsigned curTileIdx, const ChannelType _chType ) const { const CodingUnit* cu = getCU( pos, _chType ); +#if JVET_Q0151_Q0205_ENTRYPOINTS + const bool wavefrontsEnabled = this->slice->getSPS()->getEntropyCodingSyncEnabledFlag(); +#else const bool wavefrontsEnabled = this->slice->getPPS()->getEntropyCodingSyncEnabledFlag(); +#endif int ctuSizeBit = floorLog2(this->sps->getMaxCUWidth()); int xNbY = pos.x << getChannelTypeScaleX( _chType, this->area.chromaFormat ); int xCurr = curPos.x << getChannelTypeScaleX( _chType, this->area.chromaFormat ); @@ -1567,7 +1575,11 @@ const PredictionUnit* CodingStructure::getPURestricted( const Position &pos, con const PredictionUnit* pu = getPU( pos, _chType ); // exists same slice and tile pu precedes curPu in encoding order // (thus, is either from parent CS in RD-search or its index is lower) +#if JVET_Q0151_Q0205_ENTRYPOINTS + const bool wavefrontsEnabled = curPu.cu->slice->getSPS()->getEntropyCodingSyncEnabledFlag(); +#else const bool wavefrontsEnabled = curPu.cu->slice->getPPS()->getEntropyCodingSyncEnabledFlag(); +#endif int ctuSizeBit = floorLog2(curPu.cs->sps->getMaxCUWidth()); int xNbY = pos.x << getChannelTypeScaleX( _chType, curPu.chromaFormat ); int xCurr = curPu.blocks[_chType].x << getChannelTypeScaleX( _chType, curPu.chromaFormat ); @@ -1587,7 +1599,11 @@ const TransformUnit* CodingStructure::getTURestricted( const Position &pos, cons const TransformUnit* tu = getTU( pos, _chType ); // exists same slice and tile tu precedes curTu in encoding order // (thus, is either from parent CS in RD-search or its index is lower) +#if JVET_Q0151_Q0205_ENTRYPOINTS + const bool wavefrontsEnabled = curTu.cu->slice->getSPS()->getEntropyCodingSyncEnabledFlag(); +#else const bool wavefrontsEnabled = curTu.cu->slice->getPPS()->getEntropyCodingSyncEnabledFlag(); +#endif int ctuSizeBit = floorLog2(curTu.cs->sps->getMaxCUWidth()); int xNbY = pos.x << getChannelTypeScaleX( _chType, curTu.chromaFormat ); int xCurr = curTu.blocks[_chType].x << getChannelTypeScaleX( _chType, curTu.chromaFormat ); diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index a0c5ad62daf2eb12ba5b6c5984a393f4f321001d..4e2d809432cde96ff763f42019a569b72baa60b2 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -263,9 +263,36 @@ void Slice::inheritFromPicHeader( PicHeader *picHeader, const PPS *pps, const SP #endif } +#if JVET_Q0151_Q0205_ENTRYPOINTS +void Slice::setNumSubstream(const SPS* sps, const PPS* pps) +{ + uint32_t ctuAddr, ctuX, ctuY; + m_numSubstream = 0; + + // count the number of CTUs that align with either the start of a tile, or with an entropy coding sync point + // ignore the first CTU since it doesn't count as an entry point + for (uint32_t i = 1; i < m_sliceMap.getNumCtuInSlice(); i++) + { + ctuAddr = m_sliceMap.getCtuAddrInSlice(i); + ctuX = (ctuAddr % pps->getPicWidthInCtu()); + ctuY = (ctuAddr / pps->getPicWidthInCtu()); + + if (pps->ctuIsTileColBd(ctuX) && (pps->ctuIsTileRowBd(ctuY) || sps->getEntropyCodingSyncEnabledFlag())) + { + m_numSubstream++; + } + } +} + +void Slice::setNumEntryPoints(const SPS *sps, const PPS *pps) +#else void Slice::setNumEntryPoints( const PPS *pps ) +#endif { uint32_t ctuAddr, ctuX, ctuY; +#if JVET_Q0151_Q0205_ENTRYPOINTS + uint32_t prevCtuAddr, prevCtuX, prevCtuY; +#endif m_numEntryPoints = 0; // count the number of CTUs that align with either the start of a tile, or with an entropy coding sync point @@ -275,7 +302,15 @@ void Slice::setNumEntryPoints( const PPS *pps ) ctuAddr = m_sliceMap.getCtuAddrInSlice( i ); ctuX = ( ctuAddr % pps->getPicWidthInCtu() ); ctuY = ( ctuAddr / pps->getPicWidthInCtu() ); +#if JVET_Q0151_Q0205_ENTRYPOINTS + prevCtuAddr = m_sliceMap.getCtuAddrInSlice(i - 1); + prevCtuX = (prevCtuAddr % pps->getPicWidthInCtu()); + prevCtuY = (prevCtuAddr / pps->getPicWidthInCtu()); + + if (pps->ctuToTileRowBd(ctuY) != pps->ctuToTileRowBd(prevCtuY) || pps->ctuToTileColBd(ctuX) != pps->ctuToTileColBd(prevCtuX) || (ctuY != prevCtuY && sps->getEntropyCodingSyncEntryPointsPresentFlag())) +#else if( pps->ctuIsTileColBd( ctuX ) && (pps->ctuIsTileRowBd( ctuY ) || pps->getEntropyCodingSyncEnabledFlag() ) ) +#endif { m_numEntryPoints++; } @@ -2098,6 +2133,10 @@ SPS::SPS() , m_BDPCMEnabled (0) #endif , m_JointCbCrEnabledFlag (false) +#if JVET_Q0151_Q0205_ENTRYPOINTS +, m_entropyCodingSyncEnabledFlag(false) +, m_entropyCodingSyncEntryPointPresentFlag(false) +#endif , m_sbtmvpEnabledFlag (false) , m_bdofEnabledFlag (false) , m_fpelMmvdEnabledFlag ( false ) @@ -2357,7 +2396,9 @@ PPS::PPS() #if !JVET_Q0183_SPS_TRANSFORM_SKIP_MODE_CONTROL , m_log2MaxTransformSkipBlockSize (2) #endif +#if !JVET_Q0151_Q0205_ENTRYPOINTS , m_entropyCodingSyncEnabledFlag (false) +#endif , m_constantSliceHeaderParamsEnabledFlag (false) , m_PPSDepQuantEnabledIdc (0) , m_PPSRefPicListSPSIdc0 (0) diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 374d6be31194e0e722cf7c020970470e1db8b7be..ad3d25ea07904399484ed3ecb0c3c6037936a247 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1236,6 +1236,10 @@ private: bool m_JointCbCrEnabledFlag; // Parameter BitDepths m_bitDepths; +#if JVET_Q0151_Q0205_ENTRYPOINTS + bool m_entropyCodingSyncEnabledFlag; //!< Flag for enabling WPP + bool m_entropyCodingSyncEntryPointPresentFlag; //!< Flag for indicating the presence of WPP entry points + #endif int m_qpBDOffset[MAX_NUM_CHANNEL_TYPE]; int m_minQpMinus4[MAX_NUM_CHANNEL_TYPE]; // QP_internal - QP_input; @@ -1501,6 +1505,13 @@ public: int getBitDepth(ChannelType type) const { return m_bitDepths.recon[type]; } void setBitDepth(ChannelType type, int u ) { m_bitDepths.recon[type] = u; } const BitDepths& getBitDepths() const { return m_bitDepths; } + +#if JVET_Q0151_Q0205_ENTRYPOINTS + bool getEntropyCodingSyncEnabledFlag() const { return m_entropyCodingSyncEnabledFlag; } + void setEntropyCodingSyncEnabledFlag(bool val) { m_entropyCodingSyncEnabledFlag = val; } + bool getEntropyCodingSyncEntryPointsPresentFlag() const { return m_entropyCodingSyncEntryPointPresentFlag; } + void setEntropyCodingSyncEntryPointsPresentFlag(bool val) { m_entropyCodingSyncEntryPointPresentFlag = val; } +#endif int getMaxLog2TrDynamicRange(ChannelType channelType) const { return getSpsRangeExtension().getExtendedPrecisionProcessingFlag() ? std::max<int>(15, int(m_bitDepths.recon[channelType] + 6)) : 15; } int getDifferentialLumaChromaBitDepth() const { return int(m_bitDepths.recon[CHANNEL_TYPE_LUMA]) - int(m_bitDepths.recon[CHANNEL_TYPE_CHROMA]); } @@ -1791,7 +1802,9 @@ private: #if !JVET_Q0183_SPS_TRANSFORM_SKIP_MODE_CONTROL int m_log2MaxTransformSkipBlockSize; #endif +#if !JVET_Q0151_Q0205_ENTRYPOINTS bool m_entropyCodingSyncEnabledFlag; //!< Indicates the presence of wavefronts +#endif bool m_constantSliceHeaderParamsEnabledFlag; int m_PPSDepQuantEnabledIdc; @@ -2021,8 +2034,10 @@ public: uint32_t getLog2MaxTransformSkipBlockSize() const { return m_log2MaxTransformSkipBlockSize; } void setLog2MaxTransformSkipBlockSize(uint32_t u) { m_log2MaxTransformSkipBlockSize = u; } #endif +#if !JVET_Q0151_Q0205_ENTRYPOINTS bool getEntropyCodingSyncEnabledFlag() const { return m_entropyCodingSyncEnabledFlag; } void setEntropyCodingSyncEnabledFlag(bool val) { m_entropyCodingSyncEnabledFlag = val; } +#endif bool getConstantSliceHeaderParamsEnabledFlag() const { return m_constantSliceHeaderParamsEnabledFlag; } @@ -2620,6 +2635,9 @@ private: ClpRngs m_clpRngs; std::vector<uint32_t> m_substreamSizes; uint32_t m_numEntryPoints; +#if JVET_Q0151_Q0205_ENTRYPOINTS + uint32_t m_numSubstream; +#endif bool m_cabacInitFlag; @@ -2886,6 +2904,11 @@ public: uint32_t getNumberOfSubstreamSizes( ) { return (uint32_t) m_substreamSizes.size(); } void addSubstreamSize( uint32_t size ) { m_substreamSizes.push_back(size); } uint32_t getSubstreamSize( uint32_t idx ) { CHECK(idx>=getNumberOfSubstreamSizes(),"Invalid index"); return m_substreamSizes[idx]; } +#if JVET_Q0151_Q0205_ENTRYPOINTS + void resetNumberOfSubstream() { m_numSubstream = 0; } + uint32_t getNumberOfSubstream() { return (uint32_t) m_numSubstream; } + void increaseNumberOfSubstream() { m_numSubstream++; } +#endif void setCabacInitFlag( bool val ) { m_cabacInitFlag = val; } //!< set CABAC initial flag bool getCabacInitFlag() const { return m_cabacInitFlag; } //!< get CABAC initial flag @@ -2943,7 +2966,12 @@ public: void freeScaledRefPicList( Picture *scaledRefPic[] ); bool checkRPR(); const std::pair<int, int>& getScalingRatio( const RefPicList refPicList, const int refIdx ) const { CHECK( refIdx < 0, "Invalid reference index" ); return m_scalingRatio[refPicList][refIdx]; } +#if JVET_Q0151_Q0205_ENTRYPOINTS + void setNumSubstream( const SPS *sps, const PPS *pps ); + void setNumEntryPoints( const SPS *sps, const PPS *pps ); +#else void setNumEntryPoints( const PPS *pps ); +#endif uint32_t getNumEntryPoints( ) const { return m_numEntryPoints; } #if JVET_Q0795_CCALF diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 209f4f6a4833c0f005e8d485ea2a239296c5e4db..7037686803b8287bf78f86db013a05a8704ef8ae 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -147,6 +147,8 @@ #define JVET_Q0517_RPR_AFFINE_DS 1 // JVET-Q0517: affine down-sampling filters for RPR +#define JVET_Q0151_Q0205_ENTRYPOINTS 1 // JVET-Q0151 & JVET-Q0205: Make mandatory the tile offsets signalling and move the entropy_coding_sync_enabled_flag entry_point_offsets_present_flag syntax elements to the SPS from the PPS + #define JVET_O1143_SUBPIC_BOUNDARY 0 // treat subpicture boundary as picture boundary #if JVET_O1143_SUBPIC_BOUNDARY #define JVET_O1143_SUBPIC_DECCHECK 0 diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp index 762ddf16bca5d86ccdbebbc7df5b389a339a2021..429995835d7c6ee8dcd87db37646478fd2499467 100644 --- a/source/Lib/DecoderLib/DecSlice.cpp +++ b/source/Lib/DecoderLib/DecSlice.cpp @@ -48,49 +48,41 @@ // Construction/Destruction ////////////////////////////////////////////////////////////////////// -DecSlice::DecSlice() -{ -} +DecSlice::DecSlice() {} -DecSlice::~DecSlice() -{ -} +DecSlice::~DecSlice() {} -void DecSlice::create() -{ -} +void DecSlice::create() {} -void DecSlice::destroy() -{ -} +void DecSlice::destroy() {} -void DecSlice::init( CABACDecoder* cabacDecoder, DecCu* pcCuDecoder ) +void DecSlice::init(CABACDecoder *cabacDecoder, DecCu *pcCuDecoder) { - m_CABACDecoder = cabacDecoder; - m_pcCuDecoder = pcCuDecoder; + m_CABACDecoder = cabacDecoder; + m_pcCuDecoder = pcCuDecoder; } -void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int debugCTU ) +void DecSlice::decompressSlice(Slice *slice, InputBitstream *bitstream, int debugCTU) { //-- For time output for each slice slice->startProcessingTimer(); - const SPS* sps = slice->getSPS(); - Picture* pic = slice->getPic(); - CABACReader& cabacReader = *m_CABACDecoder->getCABACReader( 0 ); + const SPS * sps = slice->getSPS(); + Picture * pic = slice->getPic(); + CABACReader &cabacReader = *m_CABACDecoder->getCABACReader(0); // setup coding structure - CodingStructure& cs = *pic->cs; + CodingStructure &cs = *pic->cs; cs.slice = slice; cs.sps = sps; cs.pps = slice->getPPS(); memcpy(cs.alfApss, slice->getAlfAPSs(), sizeof(cs.alfApss)); - cs.lmcsAps = slice->getPicHeader()->getLmcsAPS(); - cs.scalinglistAps = slice->getPicHeader()->getScalingListAPS(); + cs.lmcsAps = slice->getPicHeader()->getLmcsAPS(); + cs.scalinglistAps = slice->getPicHeader()->getScalingListAPS(); - cs.pcv = slice->getPPS()->pcv; - cs.chromaQpAdj = 0; + cs.pcv = slice->getPPS()->pcv; + cs.chromaQpAdj = 0; cs.picture->resizeSAO(cs.pcv->sizeInCtus, 0); @@ -98,67 +90,72 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb if (slice->getFirstCtuRsAddrInSlice() == 0) { - cs.picture->resizeAlfCtuEnableFlag( cs.pcv->sizeInCtus ); + cs.picture->resizeAlfCtuEnableFlag(cs.pcv->sizeInCtus); cs.picture->resizeAlfCtbFilterIndex(cs.pcv->sizeInCtus); - cs.picture->resizeAlfCtuAlternative( cs.pcv->sizeInCtus ); + cs.picture->resizeAlfCtuAlternative(cs.pcv->sizeInCtus); } - const unsigned numSubstreams = slice->getNumberOfSubstreamSizes() + 1; + const unsigned numSubstreams = slice->getNumberOfSubstreamSizes() + 1; // init each couple {EntropyDecoder, Substream} // Table of extracted substreams. - std::vector<InputBitstream*> ppcSubstreams( numSubstreams ); - for( unsigned idx = 0; idx < numSubstreams; idx++ ) + std::vector<InputBitstream *> ppcSubstreams(numSubstreams); + for (unsigned idx = 0; idx < numSubstreams; idx++) { - ppcSubstreams[idx] = bitstream->extractSubstream( idx+1 < numSubstreams ? ( slice->getSubstreamSize(idx) << 3 ) : bitstream->getNumBitsLeft() ); + ppcSubstreams[idx] = bitstream->extractSubstream(idx + 1 < numSubstreams ? (slice->getSubstreamSize(idx) << 3) + : bitstream->getNumBitsLeft()); } - const unsigned widthInCtus = cs.pcv->widthInCtus; - const bool wavefrontsEnabled = cs.pps->getEntropyCodingSyncEnabledFlag(); + const unsigned widthInCtus = cs.pcv->widthInCtus; +#if JVET_Q0151_Q0205_ENTRYPOINTS + const bool wavefrontsEnabled = cs.sps->getEntropyCodingSyncEnabledFlag(); + const bool wavefrontsEntryPointPresent = cs.sps->getEntropyCodingSyncEntryPointsPresentFlag(); +#else + const bool wavefrontsEnabled = cs.pps->getEntropyCodingSyncEnabledFlag(); +#endif - cabacReader.initBitstream( ppcSubstreams[0] ); - cabacReader.initCtxModels( *slice ); + cabacReader.initBitstream(ppcSubstreams[0]); + cabacReader.initCtxModels(*slice); // Quantization parameter - pic->m_prevQP[0] = pic->m_prevQP[1] = slice->getSliceQp(); - CHECK( pic->m_prevQP[0] == std::numeric_limits<int>::max(), "Invalid previous QP" ); - - DTRACE( g_trace_ctx, D_HEADER, "=========== POC: %d ===========\n", slice->getPOC() ); + pic->m_prevQP[0] = pic->m_prevQP[1] = slice->getSliceQp(); + CHECK(pic->m_prevQP[0] == std::numeric_limits<int>::max(), "Invalid previous QP"); + DTRACE(g_trace_ctx, D_HEADER, "=========== POC: %d ===========\n", slice->getPOC()); // for every CTU in the slice segment... unsigned subStrmId = 0; - for( unsigned ctuIdx = 0; ctuIdx < slice->getNumCtuInSlice(); ctuIdx++ ) + for (unsigned ctuIdx = 0; ctuIdx < slice->getNumCtuInSlice(); ctuIdx++) { - const unsigned ctuRsAddr = slice->getCtuAddrInSlice(ctuIdx); - const unsigned ctuXPosInCtus = ctuRsAddr % widthInCtus; - const unsigned ctuYPosInCtus = ctuRsAddr / widthInCtus; - const unsigned tileColIdx = slice->getPPS()->ctuToTileCol( ctuXPosInCtus ); - const unsigned tileRowIdx = slice->getPPS()->ctuToTileRow( ctuYPosInCtus ); - const unsigned tileXPosInCtus = slice->getPPS()->getTileColumnBd( tileColIdx ); - const unsigned tileYPosInCtus = slice->getPPS()->getTileRowBd( tileRowIdx ); - const unsigned tileColWidth = slice->getPPS()->getTileColumnWidth( tileColIdx ); - const unsigned tileRowHeight = slice->getPPS()->getTileRowHeight( tileRowIdx ); - const unsigned tileIdx = slice->getPPS()->getTileIdx( ctuXPosInCtus, ctuYPosInCtus); - const unsigned maxCUSize = sps->getMaxCUWidth(); - Position pos( ctuXPosInCtus*maxCUSize, ctuYPosInCtus*maxCUSize) ; - UnitArea ctuArea(cs.area.chromaFormat, Area( pos.x, pos.y, maxCUSize, maxCUSize ) ); + const unsigned ctuRsAddr = slice->getCtuAddrInSlice(ctuIdx); + const unsigned ctuXPosInCtus = ctuRsAddr % widthInCtus; + const unsigned ctuYPosInCtus = ctuRsAddr / widthInCtus; + const unsigned tileColIdx = slice->getPPS()->ctuToTileCol(ctuXPosInCtus); + const unsigned tileRowIdx = slice->getPPS()->ctuToTileRow(ctuYPosInCtus); + const unsigned tileXPosInCtus = slice->getPPS()->getTileColumnBd(tileColIdx); + const unsigned tileYPosInCtus = slice->getPPS()->getTileRowBd(tileRowIdx); + const unsigned tileColWidth = slice->getPPS()->getTileColumnWidth(tileColIdx); + const unsigned tileRowHeight = slice->getPPS()->getTileRowHeight(tileRowIdx); + const unsigned tileIdx = slice->getPPS()->getTileIdx(ctuXPosInCtus, ctuYPosInCtus); + const unsigned maxCUSize = sps->getMaxCUWidth(); + Position pos(ctuXPosInCtus * maxCUSize, ctuYPosInCtus * maxCUSize); + UnitArea ctuArea(cs.area.chromaFormat, Area(pos.x, pos.y, maxCUSize, maxCUSize)); #if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY SubPic curSubPic = slice->getPPS()->getSubPicFromPos(pos); // padding/restore at slice level - if (curSubPic.getTreatedAsPicFlag() && ctuIdx==0) + if (curSubPic.getTreatedAsPicFlag() && ctuIdx == 0) { - int subPicX = (int)curSubPic.getSubPicLeft(); - int subPicY = (int)curSubPic.getSubPicTop(); - int subPicWidth = (int)curSubPic.getSubPicWidthInLumaSample(); - int subPicHeight = (int)curSubPic.getSubPicHeightInLumaSample(); - for (int rlist = REF_PIC_LIST_0; rlist < NUM_REF_PIC_LIST_01; rlist++) + int subPicX = (int) curSubPic.getSubPicLeft(); + int subPicY = (int) curSubPic.getSubPicTop(); + int subPicWidth = (int) curSubPic.getSubPicWidthInLumaSample(); + int subPicHeight = (int) curSubPic.getSubPicHeightInLumaSample(); + for (int rlist = REF_PIC_LIST_0; rlist < NUM_REF_PIC_LIST_01; rlist++) { - int n = slice->getNumRefIdx((RefPicList)rlist); - for (int idx = 0; idx < n; idx++) + int n = slice->getNumRefIdx((RefPicList) rlist); + for (int idx = 0; idx < n; idx++) { - Picture *refPic = slice->getRefPic((RefPicList)rlist, idx); - if (!refPic->getSubPicSaved()) + Picture *refPic = slice->getRefPic((RefPicList) rlist, idx); + if (!refPic->getSubPicSaved()) { refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight); refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight); @@ -169,29 +166,29 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb } #endif - DTRACE_UPDATE( g_trace_ctx, std::make_pair( "ctu", ctuRsAddr ) ); + DTRACE_UPDATE(g_trace_ctx, std::make_pair("ctu", ctuRsAddr)); - cabacReader.initBitstream( ppcSubstreams[subStrmId] ); + cabacReader.initBitstream(ppcSubstreams[subStrmId]); // set up CABAC contexts' state for this CTU - if( ctuXPosInCtus == tileXPosInCtus && ctuYPosInCtus == tileYPosInCtus ) + if (ctuXPosInCtus == tileXPosInCtus && ctuYPosInCtus == tileYPosInCtus) { - if( ctuIdx != 0 ) // if it is the first CTU, then the entropy coder has already been reset + if (ctuIdx != 0) // if it is the first CTU, then the entropy coder has already been reset { - cabacReader.initCtxModels( *slice ); + cabacReader.initCtxModels(*slice); cs.resetPrevPLT(cs.prevPLT); } pic->m_prevQP[0] = pic->m_prevQP[1] = slice->getSliceQp(); } - else if( ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled ) + else if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled) { // Synchronize cabac probabilities with top CTU if it's available and at the start of a line. - if( ctuIdx != 0 ) // if it is the first CTU, then the entropy coder has already been reset + if (ctuIdx != 0) // if it is the first CTU, then the entropy coder has already been reset { - cabacReader.initCtxModels( *slice ); + cabacReader.initCtxModels(*slice); cs.resetPrevPLT(cs.prevPLT); } - if( cs.getCURestricted( pos.offset(0, -1), pos, slice->getIndependentSliceIdx(), tileIdx, CH_L ) ) + if (cs.getCURestricted(pos.offset(0, -1), pos, slice->getIndependentSliceIdx(), tileIdx, CH_L)) { // Top is available, so use it. cabacReader.getCtx() = m_entropyCodingSyncContextState; @@ -203,7 +200,7 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb } bool updateBcwCodingOrder = cs.slice->getSliceType() == B_SLICE && ctuIdx == 0; - if(updateBcwCodingOrder) + if (updateBcwCodingOrder) { resetBcwCodingOrder(true, cs); } @@ -215,20 +212,20 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb cs.resetIBCBuffer = true; } - if( !cs.slice->isIntra() ) + if (!cs.slice->isIntra()) { - pic->mctsInfo.init( &cs, getCtuAddr( ctuArea.lumaPos(), *( cs.pcv ) ) ); + pic->mctsInfo.init(&cs, getCtuAddr(ctuArea.lumaPos(), *(cs.pcv))); } - if( ctuRsAddr == debugCTU ) + if (ctuRsAddr == debugCTU) { break; } - cabacReader.coding_tree_unit( cs, ctuArea, pic->m_prevQP, ctuRsAddr ); + cabacReader.coding_tree_unit(cs, ctuArea, pic->m_prevQP, ctuRsAddr); - m_pcCuDecoder->decompressCtu( cs, ctuArea ); + m_pcCuDecoder->decompressCtu(cs, ctuArea); - if( ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled ) + if (ctuXPosInCtus == tileXPosInCtus && wavefrontsEnabled) { m_entropyCodingSyncContextState = cabacReader.getCtx(); #if JVET_Q0501_PALETTE_WPP_INIT_ABOVECTU @@ -236,42 +233,52 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb #endif } - - if( ctuIdx == slice->getNumCtuInSlice()-1 ) + if (ctuIdx == slice->getNumCtuInSlice() - 1) { unsigned binVal = cabacReader.terminating_bit(); - CHECK( !binVal, "Expecting a terminating bit" ); + CHECK(!binVal, "Expecting a terminating bit"); #if DECODER_CHECK_SUBSTREAM_AND_SLICE_TRAILING_BYTES - cabacReader.remaining_bytes( false ); + cabacReader.remaining_bytes(false); #endif } - else if( ( ctuXPosInCtus + 1 == tileXPosInCtus + tileColWidth ) && - ( ctuYPosInCtus + 1 == tileYPosInCtus + tileRowHeight || wavefrontsEnabled ) ) + else if ((ctuXPosInCtus + 1 == tileXPosInCtus + tileColWidth) + && (ctuYPosInCtus + 1 == tileYPosInCtus + tileRowHeight || wavefrontsEnabled)) { // The sub-stream/stream should be terminated after this CTU. // (end of slice-segment, end of tile, end of wavefront-CTU-row) unsigned binVal = cabacReader.terminating_bit(); - CHECK( !binVal, "Expecting a terminating bit" ); + CHECK(!binVal, "Expecting a terminating bit"); +#if JVET_Q0151_Q0205_ENTRYPOINTS + bool isLastTileCtu = (ctuXPosInCtus + 1 == tileXPosInCtus + tileColWidth) && (ctuYPosInCtus + 1 == tileYPosInCtus + tileRowHeight); + if (isLastTileCtu || wavefrontsEntryPointPresent) + { +#if DECODER_CHECK_SUBSTREAM_AND_SLICE_TRAILING_BYTES + cabacReader.remaining_bytes( true ); +#endif + subStrmId++; + } +#else #if DECODER_CHECK_SUBSTREAM_AND_SLICE_TRAILING_BYTES cabacReader.remaining_bytes( true ); #endif subStrmId++; +#endif } #if JVET_O1143_MV_ACROSS_SUBPIC_BOUNDARY if (curSubPic.getTreatedAsPicFlag() && ctuIdx == (slice->getNumCtuInSlice() - 1)) // for last Ctu in the slice { - int subPicX = (int)curSubPic.getSubPicLeft(); - int subPicY = (int)curSubPic.getSubPicTop(); - int subPicWidth = (int)curSubPic.getSubPicWidthInLumaSample(); - int subPicHeight = (int)curSubPic.getSubPicHeightInLumaSample(); - for (int rlist = REF_PIC_LIST_0; rlist < NUM_REF_PIC_LIST_01; rlist++) + int subPicX = (int) curSubPic.getSubPicLeft(); + int subPicY = (int) curSubPic.getSubPicTop(); + int subPicWidth = (int) curSubPic.getSubPicWidthInLumaSample(); + int subPicHeight = (int) curSubPic.getSubPicHeightInLumaSample(); + for (int rlist = REF_PIC_LIST_0; rlist < NUM_REF_PIC_LIST_01; rlist++) { - int n = slice->getNumRefIdx((RefPicList)rlist); - for (int idx = 0; idx < n; idx++) + int n = slice->getNumRefIdx((RefPicList) rlist); + for (int idx = 0; idx < n; idx++) { - Picture *refPic = slice->getRefPic((RefPicList)rlist, idx); - if (refPic->getSubPicSaved()) + Picture *refPic = slice->getRefPic((RefPicList) rlist, idx); + if (refPic->getSubPicSaved()) { refPic->restoreSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight); refPic->setSubPicSaved(false); @@ -283,7 +290,7 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb } // deallocate all created substreams, including internal buffers. - for( auto substr: ppcSubstreams ) + for (auto substr: ppcSubstreams) { delete substr; } diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 08ed54f5ebdff357c4b67a50ab8743532ebd1a5c..fd86a2852aff70790a9483336d3f6b1096d9d4a2 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -616,7 +616,9 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetMana READ_CODE(1, uiCode, "loop_filter_across_slices_enabled_flag"); pcPPS->setLoopFilterAcrossSlicesEnabledFlag( uiCode == 1 ); } +#if !JVET_Q0151_Q0205_ENTRYPOINTS READ_FLAG(uiCode, "entropy_coding_sync_enabled_flag"); pcPPS->setEntropyCodingSyncEnabledFlag(uiCode == 1); +#endif READ_FLAG( uiCode, "cabac_init_present_flag" ); pcPPS->setCabacInitPresentFlag( uiCode ? true : false ); READ_UVLC(uiCode, "num_ref_idx_l0_default_active_minus1"); @@ -1518,6 +1520,15 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) CHECK(uiCode > 48, "Invalid min_qp_prime_ts_minus4 signalled"); #endif pcSPS->setMinQpPrimeTsMinus4(CHANNEL_TYPE_CHROMA, uiCode); + +#if JVET_Q0151_Q0205_ENTRYPOINTS + READ_FLAG( uiCode, "sps_entropy_coding_sync_enabled_flag" ); pcSPS->setEntropyCodingSyncEnabledFlag(uiCode == 1); + if (pcSPS->getEntropyCodingSyncEnabledFlag()) + { + READ_FLAG(uiCode, "sps_wpp_entry_point_offsets_present_flag"); pcSPS->setEntropyCodingSyncEntryPointsPresentFlag(uiCode == 1); + } +#endif + READ_FLAG( uiCode, "sps_weighted_pred_flag" ); pcSPS->setUseWP( uiCode ? true : false ); READ_FLAG( uiCode, "sps_weighted_bipred_flag" ); pcSPS->setUseWPBiPred( uiCode ? true : false ); @@ -3980,7 +3991,14 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par std::vector<uint32_t> entryPointOffset; +#if JVET_Q0151_Q0205_ENTRYPOINTS + pcSlice->resetNumberOfSubstream(); + pcSlice->setNumSubstream(sps, pps); + + pcSlice->setNumEntryPoints( sps, pps ); +#else pcSlice->setNumEntryPoints( pps ); +#endif if( pcSlice->getNumEntryPoints() > 0 ) { uint32_t offsetLenMinus1; diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index f38c05ff486cf3f98ffb08f81336be5eb06119b5..7451a788e99b99c3727be9bb90801a49eb998871 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -519,6 +519,9 @@ protected: //====== Sub-picture and Slices ======== bool m_singleSlicePerSubPicFlag; bool m_entropyCodingSyncEnabledFlag; +#if JVET_Q0151_Q0205_ENTRYPOINTS + bool m_entropyCodingSyncEntryPointPresentFlag; ///< flag for the presence of entry points for WPP +#endif HashType m_decodedPictureHashSEIType; @@ -1473,6 +1476,9 @@ public: bool getSaoGreedyMergeEnc () { return m_saoGreedyMergeEnc; } void setEntropyCodingSyncEnabledFlag(bool b) { m_entropyCodingSyncEnabledFlag = b; } bool getEntropyCodingSyncEnabledFlag() const { return m_entropyCodingSyncEnabledFlag; } +#if JVET_Q0151_Q0205_ENTRYPOINTS + void setEntropyCodingSyncEntryPointPresentFlag(bool b) { m_entropyCodingSyncEntryPointPresentFlag = b; } +#endif void setDecodedPictureHashSEIType(HashType m) { m_decodedPictureHashSEIType = m; } HashType getDecodedPictureHashSEIType() const { return m_decodedPictureHashSEIType; } void setBufferingPeriodSEIEnabled(bool b) { m_bufferingPeriodSEIEnabled = b; } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index e415c7d6a883945e4c164f9ad7bb0caef966e66b..c3b16b06562ff90f2b489e1e3cc9acfd194e1027 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -2702,7 +2702,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, // Allocate some coders, now the number of tiles are known. const uint32_t numberOfCtusInFrame = pcPic->cs->pcv->sizeInCtus; const int numSubstreamsColumns = pcSlice->getPPS()->getNumTileColumns(); +#if JVET_Q0151_Q0205_ENTRYPOINTS + const int numSubstreamRows = pcSlice->getSPS()->getEntropyCodingSyncEnabledFlag() ? pcPic->cs->pcv->heightInCtus : (pcSlice->getPPS()->getNumTileRows()); +#else const int numSubstreamRows = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ? pcPic->cs->pcv->heightInCtus : (pcSlice->getPPS()->getNumTileRows()); +#endif const int numSubstreams = std::max<int> (numSubstreamRows * numSubstreamsColumns, (int) pcPic->cs->pps->getNumSlicesInPic()); std::vector<OutputBitstream> substreamsOut(numSubstreams); @@ -3285,6 +3289,10 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, pcSlice->setFinalized(true); +#if JVET_Q0151_Q0205_ENTRYPOINTS + pcSlice->resetNumberOfSubstream( ); + pcSlice->setNumSubstream( pcSlice->getSPS(), pcSlice->getPPS() ); +#endif pcSlice->clearSubstreamSizes( ); { uint32_t numBinsCoded = 0; @@ -3300,7 +3308,12 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, // Append substreams... OutputBitstream *pcOut = pcBitstreamRedirect; +#if JVET_Q0151_Q0205_ENTRYPOINTS + const int numSubstreamsToCode = pcSlice->getNumberOfSubstream() + 1; +#else const int numSubstreamsToCode = pcSlice->getNumberOfSubstreamSizes()+1; +#endif + for ( uint32_t ui = 0 ; ui < numSubstreamsToCode; ui++ ) { pcOut->addSubstream(&(substreamsOut[ui])); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index f5661cb03418b4d232f368e60bb9de417edb5245..60db1a5a5a7f589ea211d7da0f7c31d0cdbbc8a7 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1347,6 +1347,11 @@ void EncLib::xInitSPS( SPS& sps, VPS& vps ) sps.setMinQpPrimeTsMinus4(ChannelType(channelType), (6 * (m_bitDepth[channelType] - m_inputBitDepth[channelType]))); } +#if JVET_Q0151_Q0205_ENTRYPOINTS + sps.setEntropyCodingSyncEnabledFlag( m_entropyCodingSyncEnabledFlag ); + sps.setEntropyCodingSyncEntryPointsPresentFlag( m_entropyCodingSyncEntryPointPresentFlag ); +#endif + sps.setUseWP( m_useWeightedPred ); sps.setUseWPBiPred( m_useWeightedBiPred ); @@ -1719,7 +1724,9 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps) pps.setSliceChromaQpFlag(m_chromaCbQpOffsetDualTree != 0 || m_chromaCrQpOffsetDualTree != 0 || m_chromaCbCrQpOffsetDualTree != 0); } - pps.setEntropyCodingSyncEnabledFlag( m_entropyCodingSyncEnabledFlag ); +#if !JVET_Q0151_Q0205_ENTRYPOINTS + pps.setEntropyCodingSyncEnabledFlag(m_entropyCodingSyncEnabledFlag); +#endif pps.setNoPicPartitionFlag( m_noPicPartitionFlag ); if( m_noPicPartitionFlag == false ) diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 449ba3af1d9f82708e8c138b0e5abecb2f179312..101589a50705d0665fe31d79b5bd46eeed5a0e7c 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1722,7 +1722,14 @@ void EncSlice::encodeSlice ( Picture* pcPic, OutputBitstream* pcSubstreams, ui { Slice *const pcSlice = pcPic->slices[getSliceSegmentIdx()]; +#if JVET_Q0151_Q0205_ENTRYPOINTS + const bool wavefrontsEnabled = pcSlice->getSPS()->getEntropyCodingSyncEnabledFlag(); + const bool wavefrontsEntryPointsFlag = (wavefrontsEnabled) ? pcSlice->getSPS()->getEntropyCodingSyncEntryPointsPresentFlag() : false; + uint32_t substreamSize = 0; + pcSlice->resetNumberOfSubstream(); +#else const bool wavefrontsEnabled = pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag(); +#endif // setup coding structure @@ -1810,7 +1817,17 @@ void EncSlice::encodeSlice ( Picture* pcPic, OutputBitstream* pcSubstreams, ui if (!isLastCTUsinSlice) //Byte alignment only when it is not the last substream in the slice { // write sub-stream size +#if JVET_Q0151_Q0205_ENTRYPOINTS + substreamSize += (pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations(); + pcSlice->increaseNumberOfSubstream(); + if( isLastCTUinTile || (isLastCTUinWPP && wavefrontsEntryPointsFlag) ) + { + pcSlice->addSubstreamSize(substreamSize); + substreamSize = 0; + } +#else pcSlice->addSubstreamSize((pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations()); +#endif } uiSubStrm++; } diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 1f0f1b672f8f246bd7d4cd543f477c0374fc3d5f..5348353d26504acbac954a986171e9096d48d361 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -376,7 +376,9 @@ void HLSWriter::codePPS( const PPS* pcPPS, const SPS* pcSPS ) WRITE_FLAG( pcPPS->getLoopFilterAcrossSlicesEnabledFlag(), "loop_filter_across_slices_enabled_flag"); } +#if !JVET_Q0151_Q0205_ENTRYPOINTS WRITE_FLAG( pcPPS->getEntropyCodingSyncEnabledFlag() ? 1 : 0, "entropy_coding_sync_enabled_flag" ); +#endif WRITE_FLAG( pcPPS->getCabacInitPresentFlag() ? 1 : 0, "cabac_init_present_flag" ); WRITE_UVLC( pcPPS->getNumRefIdxL0DefaultActive()-1, "num_ref_idx_l0_default_active_minus1"); WRITE_UVLC( pcPPS->getNumRefIdxL1DefaultActive()-1, "num_ref_idx_l1_default_active_minus1"); @@ -986,7 +988,15 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) WRITE_UVLC( pcSPS->getBitDepth(CHANNEL_TYPE_LUMA) - 8, "bit_depth_minus8" ); #if !JVET_Q0183_SPS_TRANSFORM_SKIP_MODE_CONTROL WRITE_UVLC( pcSPS->getMinQpPrimeTsMinus4(CHANNEL_TYPE_LUMA), "min_qp_prime_ts_minus4" ); -#endif +#endif +#if JVET_Q0151_Q0205_ENTRYPOINTS + WRITE_FLAG( pcSPS->getEntropyCodingSyncEnabledFlag() ? 1 : 0, "sps_entropy_coding_sync_enabled_flag" ); + if (pcSPS->getEntropyCodingSyncEnabledFlag()) + { + WRITE_FLAG( pcSPS->getEntropyCodingSyncEntryPointsPresentFlag() ? 1 : 0, "sps_wpp_entry_point_offsets_present_flag" ); + } +#endif + WRITE_FLAG( pcSPS->getUseWP() ? 1 : 0, "sps_weighted_pred_flag" ); // Use of Weighting Prediction (P_SLICE) WRITE_FLAG( pcSPS->getUseWPBiPred() ? 1 : 0, "sps_weighted_bipred_flag" ); // Use of Weighting Bi-Prediction (B_SLICE) @@ -2862,7 +2872,11 @@ void HLSWriter::codeProfileTierLevel ( const ProfileTierLevel* ptl, int maxN */ void HLSWriter::codeTilesWPPEntryPoint( Slice* pSlice ) { +#if JVET_Q0151_Q0205_ENTRYPOINTS + pSlice->setNumEntryPoints( pSlice->getSPS(), pSlice->getPPS() ); +#else pSlice->setNumEntryPoints( pSlice->getPPS() ); +#endif if( pSlice->getNumEntryPoints() == 0 ) { return;