From 3ad73c1bb76adfe9d83fa79d12a79bfa1df0853b Mon Sep 17 00:00:00 2001 From: AbeKiyo <abe.kiyo@jp.panasonic.com> Date: Fri, 8 May 2020 11:41:37 +0900 Subject: [PATCH] JVET-R0165: Optional entry point offsets. --- source/App/EncoderApp/EncApp.cpp | 4 ++++ source/App/EncoderApp/EncAppCfg.cpp | 6 ++++++ source/App/EncoderApp/EncAppCfg.h | 4 ++++ source/Lib/CommonLib/Slice.cpp | 15 +++++++++++++++ source/Lib/CommonLib/Slice.h | 9 +++++++++ source/Lib/CommonLib/TypeDef.h | 2 ++ source/Lib/DecoderLib/DecSlice.cpp | 14 ++++++++++++++ source/Lib/DecoderLib/VLCReader.cpp | 4 ++++ source/Lib/EncoderLib/EncCfg.h | 9 ++++++++- source/Lib/EncoderLib/EncLib.cpp | 4 ++++ source/Lib/EncoderLib/EncSlice.cpp | 8 ++++++++ source/Lib/EncoderLib/VLCWriter.cpp | 4 ++++ 12 files changed, 82 insertions(+), 1 deletion(-) diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index b250b5dc8..80b03d405 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -724,7 +724,11 @@ void EncApp::xInitLibCfg() m_cEncLib.setCcvSEIMaxLuminanceValue (m_ccvSEIMaxLuminanceValue); m_cEncLib.setCcvSEIAvgLuminanceValue (m_ccvSEIAvgLuminanceValue); m_cEncLib.setEntropyCodingSyncEnabledFlag ( m_entropyCodingSyncEnabledFlag ); +#if JVET_R0165_OPTIONAL_ENTRY_POINT + m_cEncLib.setEntryPointPresentFlag ( m_entryPointPresentFlag ); +#else 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 673eb6141..ee1d5da56 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1099,7 +1099,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("WeightedPredMethod,-wpM", tmpWeightedPredictionMethod, int(WP_PER_PICTURE_WITH_SIMPLE_DC_COMBINED_COMPONENT), "Weighted prediction method") ("Log2ParallelMergeLevel", m_log2ParallelMergeLevel, 2u, "Parallel merge estimation region") ("WaveFrontSynchro", m_entropyCodingSyncEnabledFlag, false, "0: entropy coding sync disabled; 1 entropy coding sync enabled") +#if JVET_R0165_OPTIONAL_ENTRY_POINT + ("EntryPointsPresent", m_entryPointPresentFlag, true, "0: entry points is not present; 1 entry points may be present in slice header") +#else ("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") @@ -1685,10 +1689,12 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) m_outputBitDepth [CHANNEL_TYPE_CHROMA] = m_outputBitDepth [CHANNEL_TYPE_LUMA ]; } +#if !JVET_R0165_OPTIONAL_ENTRY_POINT if( !m_entropyCodingSyncEnabledFlag ) { m_entropyCodingSyncEntryPointPresentFlag = false; } +#endif m_InputChromaFormatIDC = numberToChromaFormat(tmpInputChromaFormat); m_chromaFormatIDC = ((tmpChromaFormat == 0) ? (m_InputChromaFormatIDC) : (numberToChromaFormat(tmpChromaFormat))); diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 2f19e32b6..0263cb3ba 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -456,7 +456,11 @@ protected: uint32_t m_numTileRows; ///< derived number of tile rows bool m_singleSlicePerSubPicFlag; bool m_entropyCodingSyncEnabledFlag; +#if JVET_R0165_OPTIONAL_ENTRY_POINT + bool m_entryPointPresentFlag; ///< flag for the presence of entry points +#else 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/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 7de09c48e..efc1ab6e0 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -272,6 +272,13 @@ void Slice::setNumEntryPoints(const SPS *sps, const PPS *pps) uint32_t prevCtuAddr, prevCtuX, prevCtuY; m_numEntryPoints = 0; +#if JVET_R0165_OPTIONAL_ENTRY_POINT + if (!sps->getEntryPointsPresentFlag()) + { + return; + } +#endif + // 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++ ) @@ -283,7 +290,11 @@ void Slice::setNumEntryPoints(const SPS *sps, const PPS *pps) prevCtuX = (prevCtuAddr % pps->getPicWidthInCtu()); prevCtuY = (prevCtuAddr / pps->getPicWidthInCtu()); +#if JVET_R0165_OPTIONAL_ENTRY_POINT + if (pps->ctuToTileRowBd(ctuY) != pps->ctuToTileRowBd(prevCtuY) || pps->ctuToTileColBd(ctuX) != pps->ctuToTileColBd(prevCtuX) || (ctuY != prevCtuY && sps->getEntropyCodingSyncEnabledFlag())) +#else if (pps->ctuToTileRowBd(ctuY) != pps->ctuToTileRowBd(prevCtuY) || pps->ctuToTileColBd(ctuX) != pps->ctuToTileColBd(prevCtuX) || (ctuY != prevCtuY && sps->getEntropyCodingSyncEntryPointsPresentFlag())) +#endif { m_numEntryPoints++; } @@ -2402,7 +2413,11 @@ SPS::SPS() , m_BDPCMEnabledFlag (false) , m_JointCbCrEnabledFlag (false) , m_entropyCodingSyncEnabledFlag(false) +#if JVET_R0165_OPTIONAL_ENTRY_POINT +, m_entryPointPresentFlag(false) +#else , m_entropyCodingSyncEntryPointPresentFlag(false) +#endif , m_sbtmvpEnabledFlag (false) , m_bdofEnabledFlag (false) , m_fpelMmvdEnabledFlag ( false ) diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 65f2870b6..d85b6d9f6 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1287,7 +1287,11 @@ private: // Parameter BitDepths m_bitDepths; bool m_entropyCodingSyncEnabledFlag; //!< Flag for enabling WPP +#if JVET_R0165_OPTIONAL_ENTRY_POINT + bool m_entryPointPresentFlag; //!< Flag for indicating the presence of entry points +#else bool m_entropyCodingSyncEntryPointPresentFlag; //!< Flag for indicating the presence of WPP entry points +#endif int m_qpBDOffset[MAX_NUM_CHANNEL_TYPE]; #if JVET_R0045_TS_MIN_QP_CLEANUP int m_internalMinusInputBitDepth[MAX_NUM_CHANNEL_TYPE]; // max(0, internal bitdepth - input bitdepth); } @@ -1573,8 +1577,13 @@ public: bool getEntropyCodingSyncEnabledFlag() const { return m_entropyCodingSyncEnabledFlag; } void setEntropyCodingSyncEnabledFlag(bool val) { m_entropyCodingSyncEnabledFlag = val; } +#if JVET_R0165_OPTIONAL_ENTRY_POINT + bool getEntryPointsPresentFlag() const { return m_entryPointPresentFlag; } + void setEntryPointsPresentFlag(bool val) { m_entryPointPresentFlag = val; } +#else 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]); } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 4aceeb7a0..5ae5f9d07 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -52,6 +52,8 @@ //########### place macros to be removed in next cycle below this line ############### +#define JVET_R0165_OPTIONAL_ENTRY_POINT 1 // JVET-R0165: Optional entry point offset + #define R0324_PH_SYNTAX_CONDITION_MODIFY 1 // JVET-R0324 add conditions on PH syntax to conder whether current pic is bi-predictive picture #define JVET_R0130_TC_DERIVATION_BUGFIX 1 // JVET-R0130: Cleanup of tC derivation for deblocking filter diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp index 4a141bdeb..d15d90bf2 100644 --- a/source/Lib/DecoderLib/DecSlice.cpp +++ b/source/Lib/DecoderLib/DecSlice.cpp @@ -115,7 +115,11 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb const unsigned widthInCtus = cs.pcv->widthInCtus; const bool wavefrontsEnabled = cs.sps->getEntropyCodingSyncEnabledFlag(); +#if JVET_R0165_OPTIONAL_ENTRY_POINT + const bool entryPointPresent = cs.sps->getEntryPointsPresentFlag(); +#else const bool wavefrontsEntryPointPresent = cs.sps->getEntropyCodingSyncEntryPointsPresentFlag(); +#endif cabacReader.initBitstream( ppcSubstreams[0] ); cabacReader.initCtxModels( *slice ); @@ -247,6 +251,15 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb // (end of slice-segment, end of tile, end of wavefront-CTU-row) unsigned binVal = cabacReader.terminating_bit(); CHECK( !binVal, "Expecting a terminating bit" ); +#if JVET_R0165_OPTIONAL_ENTRY_POINT +#if DECODER_CHECK_SUBSTREAM_AND_SLICE_TRAILING_BYTES + cabacReader.remaining_bytes( true ); +#endif + if( entryPointPresent ) + { + subStrmId++; + } +#else bool isLastTileCtu = (ctuXPosInCtus + 1 == tileXPosInCtus + tileColWidth) && (ctuYPosInCtus + 1 == tileYPosInCtus + tileRowHeight); if( isLastTileCtu || wavefrontsEntryPointPresent ) { @@ -255,6 +268,7 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb #endif subStrmId++; } +#endif } if (slice->getPPS()->getNumSubPics() >= 2 && curSubPic.getTreatedAsPicFlag() && ctuIdx == (slice->getNumCtuInSlice() - 1)) // for last Ctu in the slice diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 56cd2438e..a94c5cab9 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -1508,10 +1508,14 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) pcSPS->setQpBDOffset(CHANNEL_TYPE_CHROMA, (int) (6*uiCode) ); READ_FLAG( uiCode, "sps_entropy_coding_sync_enabled_flag" ); pcSPS->setEntropyCodingSyncEnabledFlag(uiCode == 1); +#if JVET_R0165_OPTIONAL_ENTRY_POINT + READ_FLAG(uiCode, "sps_entry_point_offsets_present_flag"); pcSPS->setEntryPointsPresentFlag(uiCode == 1); +#else 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 ); diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index c2587682e..40e2516d8 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -486,8 +486,11 @@ protected: //====== Sub-picture and Slices ======== bool m_singleSlicePerSubPicFlag; bool m_entropyCodingSyncEnabledFlag; +#if JVET_R0165_OPTIONAL_ENTRY_POINT + bool m_entryPointPresentFlag; ///< flag for the presence of entry points +#else bool m_entropyCodingSyncEntryPointPresentFlag; ///< flag for the presence of entry points for WPP - +#endif HashType m_decodedPictureHashSEIType; bool m_bufferingPeriodSEIEnabled; @@ -1395,7 +1398,11 @@ public: bool getSaoGreedyMergeEnc () { return m_saoGreedyMergeEnc; } void setEntropyCodingSyncEnabledFlag(bool b) { m_entropyCodingSyncEnabledFlag = b; } bool getEntropyCodingSyncEnabledFlag() const { return m_entropyCodingSyncEnabledFlag; } +#if JVET_R0165_OPTIONAL_ENTRY_POINT + void setEntryPointPresentFlag(bool b) { m_entryPointPresentFlag = b; } +#else 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/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 6c9e60ef1..c310f3ecc 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -1229,7 +1229,11 @@ void EncLib::xInitSPS( SPS& sps ) } sps.setEntropyCodingSyncEnabledFlag( m_entropyCodingSyncEnabledFlag ); +#if JVET_R0165_OPTIONAL_ENTRY_POINT + sps.setEntryPointsPresentFlag( m_entryPointPresentFlag ); +#else sps.setEntropyCodingSyncEntryPointsPresentFlag( m_entropyCodingSyncEntryPointPresentFlag ); +#endif sps.setUseWP( m_useWeightedPred ); sps.setUseWPBiPred( m_useWeightedBiPred ); diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 434fecfc3..599701109 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1744,7 +1744,11 @@ void EncSlice::encodeSlice ( Picture* pcPic, OutputBitstream* pcSubstreams, ui Slice *const pcSlice = pcPic->slices[getSliceSegmentIdx()]; const bool wavefrontsEnabled = pcSlice->getSPS()->getEntropyCodingSyncEnabledFlag(); +#if JVET_R0165_OPTIONAL_ENTRY_POINT + const bool entryPointsPresentFlag = pcSlice->getSPS()->getEntryPointsPresentFlag(); +#else const bool wavefrontsEntryPointsFlag = (wavefrontsEnabled) ? pcSlice->getSPS()->getEntropyCodingSyncEntryPointsPresentFlag() : false; +#endif uint32_t substreamSize = 0; pcSlice->resetNumberOfSubstream(); @@ -1832,7 +1836,11 @@ void EncSlice::encodeSlice ( Picture* pcPic, OutputBitstream* pcSubstreams, ui // write sub-stream size substreamSize += (pcSubstreams[uiSubStrm].getNumberOfWrittenBits() >> 3) + pcSubstreams[uiSubStrm].countStartCodeEmulations(); pcSlice->increaseNumberOfSubstream(); +#if JVET_R0165_OPTIONAL_ENTRY_POINT + if( entryPointsPresentFlag ) +#else if( isLastCTUinTile || (isLastCTUinWPP && wavefrontsEntryPointsFlag) ) +#endif { pcSlice->addSubstreamSize(substreamSize); substreamSize = 0; diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index fd3581ebe..ed9c374e6 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -909,10 +909,14 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) WRITE_UVLC( pcSPS->getBitDepth(CHANNEL_TYPE_LUMA) - 8, "bit_depth_minus8" ); WRITE_FLAG( pcSPS->getEntropyCodingSyncEnabledFlag() ? 1 : 0, "sps_entropy_coding_sync_enabled_flag" ); +#if JVET_R0165_OPTIONAL_ENTRY_POINT + WRITE_FLAG( pcSPS->getEntryPointsPresentFlag() ? 1 : 0, "sps_entry_point_offsets_present_flag" ); +#else 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) -- GitLab