From f5d1f77d010e34781c8f92137d673ad93c037142 Mon Sep 17 00:00:00 2001 From: zhipin <zhipin.deng@bytedance.com> Date: Fri, 15 May 2020 12:32:06 +0800 Subject: [PATCH] JVET-R0058: the combination of RPR, subpictures, and scalability --- cfg/multi-layer/two_layers_ELonlyILP.cfg | 29 +++ ...llText_subpicture_4_slice_2_hor_subpic.cfg | 48 +++++ source/App/EncoderApp/EncApp.cpp | 22 ++- source/App/EncoderApp/EncAppCfg.cpp | 25 ++- source/App/EncoderApp/EncAppCfg.h | 8 + source/Lib/CommonLib/InterPrediction.cpp | 12 +- source/Lib/CommonLib/Mv.cpp | 52 +++++ source/Lib/CommonLib/Mv.h | 7 +- source/Lib/CommonLib/Slice.cpp | 9 + source/Lib/CommonLib/Slice.h | 14 ++ source/Lib/CommonLib/TypeDef.h | 1 + source/Lib/CommonLib/UnitTools.cpp | 55 ++++++ source/Lib/CommonLib/UnitTools.h | 3 + source/Lib/DecoderLib/DecLib.cpp | 25 ++- source/Lib/DecoderLib/DecSlice.cpp | 15 +- source/Lib/DecoderLib/VLCReader.cpp | 14 +- source/Lib/EncoderLib/EncCfg.h | 11 +- source/Lib/EncoderLib/EncGOP.cpp | 181 ++++++++++++------ source/Lib/EncoderLib/EncLib.cpp | 47 ++++- source/Lib/EncoderLib/EncLib.h | 7 +- source/Lib/EncoderLib/EncSlice.cpp | 6 +- source/Lib/EncoderLib/InterSearch.cpp | 29 +-- source/Lib/EncoderLib/InterSearch.h | 6 + source/Lib/EncoderLib/VLCWriter.cpp | 11 +- 24 files changed, 536 insertions(+), 101 deletions(-) create mode 100644 cfg/multi-layer/two_layers_ELonlyILP.cfg create mode 100644 cfg/partitioning/BasketballDrillText_subpicture_4_slice_2_hor_subpic.cfg diff --git a/cfg/multi-layer/two_layers_ELonlyILP.cfg b/cfg/multi-layer/two_layers_ELonlyILP.cfg new file mode 100644 index 0000000000..3bca520408 --- /dev/null +++ b/cfg/multi-layer/two_layers_ELonlyILP.cfg @@ -0,0 +1,29 @@ +#======== Layers =============== +MaxLayers : 2 +MaxSublayers : 1 +AllLayersSameNumSublayersFlag : 0 +AllIndependentLayersFlag : 0 +AllowablePredDirection : 1 1 1 1 1 # equal to 0 specifies the picture in the i-th temporal layer is allowed to use both inter-layer and intra-layer preditions + # equal to 1 specifies the picture in the i-th temporal layer is allowed to use inter-layer predition only + # equal to 2 specifies the picture in the i-th temporal layer is allowed to use intra-layer predition only + +#======== OLSs =============== +EachLayerIsAnOlsFlag : 0 +OlsModeIdc : 2 +NumOutputLayerSets : 2 +OlsOutputLayer1 : 1 0 +NumPTLsInVPS : 2 +#======== Layer-0 =============== +LayerId0 : 0 +#======== Layer-1 =============== +LayerId1 : 1 +NumRefLayers1 : 1 +RefLayerIdx1 : 0 +#======== OLS-0 =============== +OlsPTLIdx0 : 0 +#======== OLS-1 =============== +LevelPTL1 : 6.2 +OlsPTLIdx1 : 1 + + + diff --git a/cfg/partitioning/BasketballDrillText_subpicture_4_slice_2_hor_subpic.cfg b/cfg/partitioning/BasketballDrillText_subpicture_4_slice_2_hor_subpic.cfg new file mode 100644 index 0000000000..e72abb0145 --- /dev/null +++ b/cfg/partitioning/BasketballDrillText_subpicture_4_slice_2_hor_subpic.cfg @@ -0,0 +1,48 @@ +#======== File I/O =============== +InputFile : BasketballDrillText_832x480_50.yuv +InputBitDepth : 8 # Input bitdepth +InputChromaFormat : 420 # Ratio of luminance to chrominance samples +FrameRate : 50 # Frame Rate per second +FrameSkip : 0 # Number of frames to be skipped in input +SourceWidth : 832 # Input frame width +SourceHeight : 480 # Input frame height +FramesToBeEncoded : 500 # Number of frames to be coded + +Level : 3.1 + +#============ Subpictures ================== +# example cfg file, assuming an 832x480 input sequence with CTU size = 128x128, and split to 4 rectangular slices, each slice include one tile. +# example 2 subpictures in a 832x480 picture: +#---------- +#| | | +#| | | +#|----|---|--> horizontally divided into 2 subpicture, each subpicture contains two slices +#| | | +#| | | +#---------- + +SubPicInfoPresentFlag : 1 # subpicture information present flag(0: OFF, 1: ON) +NumSubPics : 2 # number of subpictures in a picture +SubPicCtuTopLeftX : 0 0 # specifies horizontal position of top left CTU of i-th subpicture in unit of CtbSizeY +SubPicCtuTopLeftY : 0 2 # specifies vertical position of top left CTU of i-th subpicture in unit of CtbSizeY +SubPicWidth : 7 7 # specifies the width of the i-th subpicture in units of CtbSizeY +SubPicHeight : 2 2 # specifies the height of the i-th subpicture in units of CtbSizeY +SubPicTreatedAsPicFlag : 1 1 # equal to 1 specifies that the i-th subpicture of each coded picture in the CLVS is treated as a picture in the decoding process excluding in-loop filtering operations +LoopFilterAcrossSubpicEnabledFlag : 0 0 # equal to 1 specifies that in-loop filtering operations may be performed across the boundaries of the i-th subpicture in each coded picture in the CLVS +SubPicIdMappingExplicitlySignalledFlag : 0 # equal to 1 specifies that the subpicture ID mapping is explicitly signalled, either in the SPS or in the PPSs +SubPicIdMappingInSpsFlag : 0 # specifies that subpicture ID mapping is signalled in the SPS(0: OFF, 1: ON) +SubPicIdLen : 0 # the number of bits used to represent the syntax element sps_subpic_id[ i ] +SubPicId : 0 # subpicture ID of the i-th subpicture + + +#============ Tiles / Slices ================ +EnablePicPartitioning : 1 # Enable picture partitioning (0: single tile, single slice, 1: multiple tiles/slices can be used) + +# 24 tiles and 6 rectangular slices +TileColumnWidthArray : 4 # Tile column widths in units of CTUs. Last column width will be repeated uniformly to cover any remaining picture width +TileRowHeightArray : 2 # Tile row heights in units of CTUs. Last row height will be repeated uniformly to cover any remaining picture height +RasterScanSlices : 0 # Raster-scan or rectangular slices (0: rectangular, 1: raster-scan) +RectSliceFixedWidth : 1 # Fixed rectangular slice width in units of tiles (0: disable this feature and use RectSlicePositions instead) +RectSliceFixedHeight : 1 # Fixed rectangular slice height in units of tiles (0: disable this feature and use RectSlicePositions instead) +DisableLoopFilterAcrossTiles : 1 # Loop filtering (DBLK/SAO/ALF) applied across tile boundaries or not (0: filter across tile boundaries 1: do not filter across tile boundaries) +DisableLoopFilterAcrossSlices : 1 # Loop filtering (DBLK/SAO/ALF) applied across slice boundaries or not (0: filter across slice boundaries 1: do not filter across slice boundaries) diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 9f293af2c2..c9004e6120 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -103,6 +103,19 @@ void EncApp::xInitLibCfg() if (!vps.getAllIndependentLayersFlag()) { vps.setEachLayerIsAnOlsFlag(0); +#if JVET_R0058 + for (int i = 0; i < m_maxTempLayer; i++) + { + vps.setPredDirection(i, 0); + } + for (int i = 0; i < m_predDirectionArray.size(); i++) + { + if (m_predDirectionArray[i] != ' ') + { + vps.setPredDirection(i >> 1, int(m_predDirectionArray[i] - 48)); + } + } +#endif } } @@ -114,7 +127,6 @@ void EncApp::xInitLibCfg() if (i > 0 && !vps.getAllIndependentLayersFlag()) { vps.setIndependentLayerFlag( i, m_numRefLayers[i] ? false : true ); - if (!vps.getIndependentLayerFlag(i)) { for (int j = 0, k = 0; j < i; j++) @@ -238,7 +250,11 @@ void EncApp::xInitLibCfg() m_cEncLib.setSourceHeight ( m_iSourceHeight ); m_cEncLib.setConformanceWindow ( m_confWinLeft / SPS::getWinUnitX( m_InputChromaFormatIDC ), m_confWinRight / SPS::getWinUnitX( m_InputChromaFormatIDC ), m_confWinTop / SPS::getWinUnitY( m_InputChromaFormatIDC ), m_confWinBottom / SPS::getWinUnitY( m_InputChromaFormatIDC ) ); m_cEncLib.setScalingRatio ( m_scalingRatioHor, m_scalingRatioVer ); +#if JVET_R0058 + m_cEncLib.setResChangeInClvsEnabled ( m_resChangeInClvsEnabled ); +#else m_cEncLib.setRPREnabled ( m_rprEnabled ); +#endif m_cEncLib.setSwitchPocPeriod ( m_switchPocPeriod ); m_cEncLib.setUpscaledOutput ( m_upscaledOutput ); m_cEncLib.setFramesToBeEncoded ( m_framesToBeEncoded ); @@ -1149,7 +1165,11 @@ void EncApp::xWriteOutput( int iNumEncoded, std::list<PelUnitBuf*>& recBufList ) const PelUnitBuf* pcPicYuvRec = *(iterPicYuvRec++); if (!m_reconFileName.empty()) { +#if JVET_R0058 + if( m_cEncLib.isResChangeInClvsEnabled() && m_cEncLib.getUpscaledOutput() ) +#else if( m_cEncLib.isRPREnabled() && m_cEncLib.getUpscaledOutput() ) +#endif { const SPS& sps = *m_cEncLib.getSPS( 0 ); const PPS& pps = *m_cEncLib.getPPS( ( sps.getMaxPicWidthInLumaSamples() != pcPicYuvRec->get( COMPONENT_Y ).width || sps.getMaxPicHeightInLumaSamples() != pcPicYuvRec->get( COMPONENT_Y ).height ) ? ENC_PPS_ID_RPR : 0 ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 497afeedd9..fb988e9b06 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1382,6 +1382,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ( "MaxSublayers", m_maxSublayers, 1, "Max number of Sublayers") ( "AllLayersSameNumSublayersFlag", m_allLayersSameNumSublayersFlag, true, "All layers same num sublayersflag") ( "AllIndependentLayersFlag", m_allIndependentLayersFlag, true, "All layers are independent layer") +#if JVET_R0058 + ("AllowablePredDirection", m_predDirectionArray, string(""), "prediction directions allowed for i-th temporal layer") +#endif ( "LayerId%d", m_layerId, 0, MAX_VPS_LAYERS, "Max number of Sublayers") ( "NumRefLayers%d", m_numRefLayers, 0, MAX_VPS_LAYERS, "Number of direct reference layer index of i-th layer") ( "RefLayerIdx%d", m_refLayerIdxStr, string(""), MAX_VPS_LAYERS, "Reference layer index(es)") @@ -1425,13 +1428,21 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) po::ErrorReporter err; const list<const char*>& argv_unhandled = po::scanArgv(opts, argc, (const char**) argv, err); +#if JVET_R0058 + m_resChangeInClvsEnabled = m_scalingRatioHor != 1.0 || m_scalingRatioVer != 1.0; +#else m_rprEnabled = m_scalingRatioHor != 1.0 || m_scalingRatioVer != 1.0; +#endif if( m_fractionOfFrames != 1.0 ) { m_framesToBeEncoded = int( m_framesToBeEncoded * m_fractionOfFrames ); } - if( m_rprEnabled && !m_switchPocPeriod ) +#if JVET_R0058 + if (m_resChangeInClvsEnabled && !m_switchPocPeriod) +#else + if (m_rprEnabled && !m_switchPocPeriod) +#endif { m_switchPocPeriod = m_iFrameRate / 2 / m_iGOPSize * m_iGOPSize; } @@ -1628,7 +1639,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) } CHECK( m_subPicIdLen > 16, "SubPicIdLen must not exceed 16 bits" ); - CHECK( m_rprEnabled, "RPR and subpictures cannot be enabled together" ); +#if JVET_R0058 + CHECK(m_resChangeInClvsEnabled, "resolution change in CLVS and subpictures cannot be enabled together"); +#else + CHECK(m_rprEnabled, "RPR and subpictures cannot be enabled together"); +#endif } if (m_cfgSubpictureLevelInfoSEI.m_enabled) @@ -3828,7 +3843,11 @@ void EncAppCfg::xPrintParameter() msg( VERBOSE, "NumWppThreads:%d+%d ", m_numWppThreads, m_numWppExtraLines ); msg( VERBOSE, "EnsureWppBitEqual:%d ", m_ensureWppBitEqual ); - if( m_rprEnabled ) +#if JVET_R0058 + if (m_resChangeInClvsEnabled) +#else + if (m_rprEnabled) +#endif { msg( VERBOSE, "RPR:(%1.2lfx, %1.2lfx)|%d ", m_scalingRatioHor, m_scalingRatioVer, m_switchPocPeriod ); } diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 6bd0a61c2f..c995933d72 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -706,7 +706,11 @@ protected: double m_scalingRatioHor; double m_scalingRatioVer; +#if JVET_R0058 + bool m_resChangeInClvsEnabled; +#else bool m_rprEnabled; +#endif double m_fractionOfFrames; ///< encode a fraction of the frames as specified in FramesToBeEncoded int m_switchPocPeriod; int m_upscaledOutput; ////< Output upscaled (2), decoded cropped but in full resolution buffer (1) or decoded cropped (0, default) picture for RPR. @@ -723,6 +727,10 @@ protected: int m_maxSublayers; bool m_allLayersSameNumSublayersFlag; bool m_allIndependentLayersFlag; +#if JVET_R0058 + std::string m_predDirectionArray; +#endif + int m_numRefLayers[MAX_VPS_LAYERS]; std::string m_refLayerIdxStr[MAX_VPS_LAYERS]; bool m_eachLayerIsAnOlsFlag; diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index 0a7e905303..ac3ac1feaf 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -476,7 +476,11 @@ void InterPrediction::xPredInterUni(const PredictionUnit& pu, const RefPicList& if( !pu.cu->affine ) { +#if JVET_R0058 + if (!isIBC) +#else if( !isIBC && pu.cu->slice->getRefPic( eRefPicList, iRefIdx )->isRefScaled( pu.cs->pps ) == false ) +#endif { #if JVET_Q0764_WRAP_AROUND_WITH_RPR if( !pu.cs->pps->getWrapAroundEnabledFlag() ) @@ -1095,7 +1099,9 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction { wrapRef = false; m_storedMv[h / AFFINE_MIN_BLOCK_SIZE * MVBUFFER_SIZE + w / AFFINE_MIN_BLOCK_SIZE].set(iMvScaleTmpHor, iMvScaleTmpVer); - if( refPic->isRefScaled( pu.cs->pps ) == false ) +#if !JVET_R0058 + if (refPic->isRefScaled(pu.cs->pps) == false) +#endif { clipMv(tmpMv, pu.lumaPos(), pu.lumaSize(), *pu.cs->sps, *pu.cs->pps); iMvScaleTmpHor = tmpMv.getHor(); @@ -1119,7 +1125,9 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction else { wrapRef = false; - if( refPic->isRefScaled( pu.cs->pps ) == false ) +#if !JVET_R0058 + if (refPic->isRefScaled(pu.cs->pps) == false) +#endif { clipMv(curMv, pu.lumaPos(), pu.lumaSize(), *pu.cs->sps, *pu.cs->pps); } diff --git a/source/Lib/CommonLib/Mv.cpp b/source/Lib/CommonLib/Mv.cpp index 2bfb1333a9..528c3c4dde 100644 --- a/source/Lib/CommonLib/Mv.cpp +++ b/source/Lib/CommonLib/Mv.cpp @@ -51,6 +51,57 @@ void roundAffineMv( int& mvx, int& mvy, int nShift ) mvy = (mvy + nOffset - (mvy >= 0)) >> nShift; } +#if JVET_R0058 +void (*clipMv) ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps ); + +void clipMvInPic ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps ) +{ + if (sps.getWrapAroundEnabledFlag()) + { + wrapClipMv(rcMv, pos, size, &sps, &pps); + return; + } + + int iMvShift = MV_FRACTIONAL_BITS_INTERNAL; + int iOffset = 8; + int iHorMax = (pps.getPicWidthInLumaSamples() + iOffset - (int)pos.x - 1) << iMvShift; + int iHorMin = (-(int)sps.getMaxCUWidth() - iOffset - (int)pos.x + 1) << iMvShift; + + int iVerMax = (pps.getPicHeightInLumaSamples() + iOffset - (int)pos.y - 1) << iMvShift; + int iVerMin = (-(int)sps.getMaxCUHeight() - iOffset - (int)pos.y + 1) << iMvShift; + + rcMv.setHor(std::min(iHorMax, std::max(iHorMin, rcMv.getHor()))); + rcMv.setVer(std::min(iVerMax, std::max(iVerMin, rcMv.getVer()))); +} + +void clipMvInSubpic ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps ) +{ + if (sps.getWrapAroundEnabledFlag()) + { + wrapClipMv(rcMv, pos, size, &sps, &pps); + return; + } + + int iMvShift = MV_FRACTIONAL_BITS_INTERNAL; + int iOffset = 8; + int iHorMax = (pps.getPicWidthInLumaSamples() + iOffset - (int)pos.x - 1) << iMvShift; + int iHorMin = (-(int)sps.getMaxCUWidth() - iOffset - (int)pos.x + 1) << iMvShift; + + int iVerMax = (pps.getPicHeightInLumaSamples() + iOffset - (int)pos.y - 1) << iMvShift; + int iVerMin = (-(int)sps.getMaxCUHeight() - iOffset - (int)pos.y + 1) << iMvShift; + const SubPic& curSubPic = pps.getSubPicFromPos(pos); + if (curSubPic.getTreatedAsPicFlag()) + { + iHorMax = ((curSubPic.getSubPicRight() + 1) + iOffset - (int)pos.x - 1) << iMvShift; + iHorMin = (-(int)sps.getMaxCUWidth() - iOffset - ((int)pos.x - curSubPic.getSubPicLeft()) + 1) << iMvShift; + + iVerMax = ((curSubPic.getSubPicBottom() + 1) + iOffset - (int)pos.y - 1) << iMvShift; + iVerMin = (-(int)sps.getMaxCUHeight() - iOffset - ((int)pos.y - curSubPic.getSubPicTop()) + 1) << iMvShift; + } + rcMv.setHor(std::min(iHorMax, std::max(iHorMin, rcMv.getHor()))); + rcMv.setVer(std::min(iVerMax, std::max(iVerMin, rcMv.getVer()))); +} +#else void clipMv( Mv& rcMv, const Position& pos, const struct Size& size, const SPS& sps, const PPS& pps ) { #if JVET_Q0764_WRAP_AROUND_WITH_RPR @@ -82,6 +133,7 @@ void clipMv( Mv& rcMv, const Position& pos, const struct Size& size, const SPS& rcMv.setHor( std::min( iHorMax, std::max( iHorMin, rcMv.getHor() ) ) ); rcMv.setVer( std::min( iVerMax, std::max( iVerMin, rcMv.getVer() ) ) ); } +#endif bool wrapClipMv( Mv& rcMv, const Position& pos, const struct Size& size, const SPS *sps, const PPS *pps ) { diff --git a/source/Lib/CommonLib/Mv.h b/source/Lib/CommonLib/Mv.h index e06db56a94..f019c3a74f 100644 --- a/source/Lib/CommonLib/Mv.h +++ b/source/Lib/CommonLib/Mv.h @@ -281,12 +281,17 @@ namespace std } }; }; +#if JVET_R0058 +extern void(*clipMv) ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps ); +void clipMvInPic ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps ); +void clipMvInSubpic ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps, const class PPS& pps ); +#else void clipMv ( Mv& rcMv, const struct Position& pos, const struct Size& size, const class SPS& sps , const class PPS& pps ); - +#endif bool wrapClipMv( Mv& rcMv, const Position& pos, const struct Size& size, const SPS *sps diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index b70cd57675..b6d8ff6d7c 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -1961,6 +1961,12 @@ VPS::VPS() , m_sublayerDpbParamsPresentFlag( false ) , m_targetOlsIdx( -1 ) { +#if JVET_R0058 + for (int i = 0; i < MAX_VPS_SUBLAYERS; i++) + { + m_vpsCfgPredDirection[i] = 0; + } +#endif for (int i = 0; i < MAX_VPS_LAYERS; i++) { m_vpsLayerId[i] = 0; @@ -2505,6 +2511,9 @@ SPS::SPS() , m_GDREnabledFlag ( true ) , m_SubLayerCbpParametersPresentFlag ( true ) , m_rprEnabledFlag ( false ) +#if JVET_R0058 +, m_resChangeInClvsEnabledFlag ( false ) +#endif , m_maxNumMergeCand(MRG_MAX_NUM_CANDS) , m_maxNumAffineMergeCand(AFFINE_MRG_MAX_NUM_CANDS) , m_maxNumIBCMergeCand(IBC_MRG_MAX_NUM_CANDS) diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index fada6a97b8..293a1d0e03 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -928,6 +928,9 @@ private: uint32_t m_vpsLayerId[MAX_VPS_LAYERS]; bool m_vpsAllLayersSameNumSubLayersFlag; bool m_vpsAllIndependentLayersFlag; +#if JVET_R0058 + uint32_t m_vpsCfgPredDirection[MAX_VPS_SUBLAYERS]; +#endif bool m_vpsIndependentLayerFlag[MAX_VPS_LAYERS]; bool m_vpsDirectRefLayerFlag[MAX_VPS_LAYERS][MAX_VPS_LAYERS]; bool m_vpsEachLayerIsAnOlsFlag; @@ -994,6 +997,10 @@ public: bool getAllIndependentLayersFlag() const { return m_vpsAllIndependentLayersFlag; } void setAllIndependentLayersFlag(bool t) { m_vpsAllIndependentLayersFlag = t; } +#if JVET_R0058 + uint32_t getPredDirection(uint32_t tmplayer) const { return m_vpsCfgPredDirection[tmplayer]; } + void setPredDirection(uint32_t tmplayer, uint32_t t) { m_vpsCfgPredDirection[tmplayer] = t; } +#endif bool getIndependentLayerFlag(uint32_t layerIdx) const { return m_vpsIndependentLayerFlag[layerIdx]; } void setIndependentLayerFlag(uint32_t layerIdx, bool t) { m_vpsIndependentLayerFlag[layerIdx] = t; } @@ -1460,6 +1467,9 @@ private: bool m_SubLayerCbpParametersPresentFlag; bool m_rprEnabledFlag; +#if JVET_R0058 + bool m_resChangeInClvsEnabledFlag; +#endif bool m_interLayerPresentFlag; uint32_t m_log2ParallelMergeLevelMinus2; @@ -1849,6 +1859,10 @@ void setCCALFEnabledFlag( bool b ) void setRprEnabledFlag( bool flag ) { m_rprEnabledFlag = flag; } bool getInterLayerPresentFlag() const { return m_interLayerPresentFlag; } void setInterLayerPresentFlag( bool b ) { m_interLayerPresentFlag = b; } +#if JVET_R0058 + bool getResChangeInClvsEnabledFlag() const { return m_resChangeInClvsEnabledFlag; } + void setResChangeInClvsEnabledFlag(bool flag) { m_resChangeInClvsEnabledFlag = flag; } +#endif uint32_t getLog2ParallelMergeLevelMinus2() const { return m_log2ParallelMergeLevelMinus2; } void setLog2ParallelMergeLevelMinus2(uint32_t mrgLevel) { m_log2ParallelMergeLevelMinus2 = mrgLevel; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index b62daf9ea5..143465b767 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -51,6 +51,7 @@ #include <cassert> //########### place macros to be removed in next cycle below this line ############### +#define JVET_R0058 1 // JVET-R0058: the combination of RPR, subpictures, and scalability #define JVET_Q0764_WRAP_AROUND_WITH_RPR 1 // JVET-Q0764: Combination of wrap around offset and RPR diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 444ff8b327..2bb4a1dff1 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -135,6 +135,61 @@ bool CU::getRprScaling( const SPS* sps, const PPS* curPPS, Picture* refPic, int& return refPic->isRefScaled( curPPS ); } +#if JVET_R0058 +void CU::isConformanceILRP(Slice *slice) +{ + const int numRefList = (slice->getSliceType() == B_SLICE) ? (2) : (1); + + //constraint 1: The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] has the same subpicture layout as the current picture + bool isAllRefSameSubpicLayout = true; + for (int iNumRef = 0; iNumRef < numRefList; iNumRef++) // loop over l0 and l1 + { + RefPicList eRefPicList = (iNumRef ? REF_PIC_LIST_1 : REF_PIC_LIST_0); + for (int iRefIdx = 0; iRefIdx < slice->getNumRefIdx(eRefPicList); iRefIdx++) + { + const Picture* refPic = slice->getRefPic(eRefPicList, iRefIdx); + + if (refPic->cs->pps->getNumSubPics() != slice->getPic()->cs->pps->getNumSubPics()) + { + isAllRefSameSubpicLayout = false; + goto outloopCon1; + } + else + { + for (int i = 0; i < slice->getPic()->cs->pps->getNumSubPics(); i++) + { + if (refPic->cs->pps->getSubPic(i).getSubPicWidthInCTUs() != slice->getPic()->cs->pps->getSubPic(i).getSubPicWidthInCTUs() + || refPic->cs->pps->getSubPic(i).getSubPicHeightInCTUs() != slice->getPic()->cs->pps->getSubPic(i).getSubPicHeightInCTUs() + || refPic->cs->pps->getSubPic(i).getSubPicCtuTopLeftX() != slice->getPic()->cs->pps->getSubPic(i).getSubPicCtuTopLeftX() + || refPic->cs->pps->getSubPic(i).getSubPicCtuTopLeftY() != slice->getPic()->cs->pps->getSubPic(i).getSubPicCtuTopLeftY()) + { + isAllRefSameSubpicLayout = false; + goto outloopCon1; + } + } + } + } + } +outloopCon1: + + //constraint 2: The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] is an ILRP for which the value of sps_num_subpics_minus1 is equal to 0 + if (!isAllRefSameSubpicLayout) + { + for (int iNumRef = 0; iNumRef < numRefList; iNumRef++) // loop over l0 and l1 + { + RefPicList eRefPicList = (iNumRef ? REF_PIC_LIST_1 : REF_PIC_LIST_0); + for (int iRefIdx = 0; iRefIdx < slice->getNumRefIdx(eRefPicList); iRefIdx++) + { + const Picture* refPic = slice->getRefPic(eRefPicList, iRefIdx)->unscaledPic; + CHECK(!(refPic->layerId != slice->getPic()->layerId && refPic->cs->pps->getNumSubPics() == 1), "The inter-layer reference shall contain a single subpicture or have same subpicture layout with the current picture"); + } + } + } + + return; +} +#endif + bool CU::isIntra(const CodingUnit &cu) { return cu.predMode == MODE_INTRA; diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index 9f6f0cfcf1..b4e4b342cd 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -122,6 +122,9 @@ namespace CU bool isSbtMode (const uint8_t sbtInfo); bool isSameSbtSize (const uint8_t sbtInfo1, const uint8_t sbtInfo2); bool getRprScaling ( const SPS* sps, const PPS* curPPS, Picture* refPic, int& xScale, int& yScale ); +#if JVET_R0058 + void isConformanceILRP (Slice *slice); +#endif } // PU tools namespace PU diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index e7403050c2..e3ede012d2 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -563,7 +563,11 @@ Picture* DecLib::xGetNewPicBuffer( const SPS &sps, const PPS &pps, const uint32_ } else { +#if JVET_R0058 + if( !pcPic->Y().Size::operator==( Size( pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples() ) ) || pps.pcv->maxCUWidth != sps.getMaxCUWidth() || pps.pcv->maxCUHeight != sps.getMaxCUHeight() || pcPic->layerId != layerId ) +#else if( !pcPic->Y().Size::operator==( Size( pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples() ) ) || pps.pcv->maxCUWidth != sps.getMaxCUWidth() || pps.pcv->maxCUHeight != sps.getMaxCUHeight() ) +#endif { pcPic->destroy(); pcPic->create( sps.getChromaFormatIdc(), Size( pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples() ), sps.getMaxCUWidth(), sps.getMaxCUWidth() + 16, true, layerId ); @@ -1406,6 +1410,18 @@ void DecLib::xCheckParameterSetConstraints(const int layerId) const int minCuSize = 1 << sps->getLog2MinCodingBlockSize(); CHECK( ( pps->getPicWidthInLumaSamples() % ( std::max( 8, minCuSize) ) ) != 0, "Coded frame width must be a multiple of Max(8, the minimum unit size)" ); CHECK( ( pps->getPicHeightInLumaSamples() % ( std::max( 8, minCuSize) ) ) != 0, "Coded frame height must be a multiple of Max(8, the minimum unit size)" ); +#if JVET_R0058 + if (!sps->getResChangeInClvsEnabledFlag()) + { + CHECK(pps->getPicWidthInLumaSamples() != sps->getMaxPicWidthInLumaSamples(), "When res_change_in_clvs_allowed_flag equal to 0, the value of pic_width_in_luma_samples shall be equal to pic_width_max_in_luma_samples."); + CHECK(pps->getPicHeightInLumaSamples() != sps->getMaxPicHeightInLumaSamples(), "When res_change_in_clvs_allowed_flag equal to 0, the value of pic_height_in_luma_samples shall be equal to pic_height_max_in_luma_samples."); + } + if (sps->getResChangeInClvsEnabledFlag()) + { + CHECK(sps->getSubPicInfoPresentFlag() != 0, "When res_change_in_clvs_allowed_flag is equal to 1, the value of subpic_info_present_flag shall be equal to 0."); + } + CHECK(sps->getResChangeInClvsEnabledFlag() && sps->getVirtualBoundariesEnabledFlag(), "when the value of res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0"); +#else if( !sps->getRprEnabledFlag() ) { CHECK( pps->getPicWidthInLumaSamples() != sps->getMaxPicWidthInLumaSamples(), "When res_change_in_clvs_allowed_flag equal to 0, the value of pic_width_in_luma_samples shall be equal to pic_width_max_in_luma_samples." ); @@ -1417,6 +1433,7 @@ void DecLib::xCheckParameterSetConstraints(const int layerId) } CHECK( sps->getRprEnabledFlag() && sps->getVirtualBoundariesPresentFlag(), "when the value of res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0" ); +#endif if( sps->getCTUSize() + 2 * ( 1 << sps->getLog2MinCodingBlockSize() ) > pps->getPicWidthInLumaSamples() ) { @@ -1526,12 +1543,10 @@ void DecLib::xCheckParameterSetConstraints(const int layerId) CHECK( currentSubPicIdx == NOT_VALID, "Sub-picture was not found" ); CHECK( !previousSubPicIds.count( layerId ), "Sub-picture information of the previously decoded picture was not stored" ); - if( previousSubPicIds[layerId][currentSubPicIdx] != slice->getSliceSubPicId() ) { CHECK( !slice->isIRAP(), "For reordered sub-pictures, the slice NAL shall be in the range of IDR_W_RADL to CRA_NUT, inclusive" ) } - // store PPS ID to have sub-picture info for the next pictures when last rectangular slice in the picture is encountered if( slice->getSliceID() + 1 == pps->getNumSlicesInPic() ) { @@ -1922,6 +1937,12 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl pcSlice->constructRefPicList(m_cListPic); pcSlice->checkRPL(pcSlice->getRPL0(), pcSlice->getRPL1(), m_associatedIRAPDecodingOrderNumber, m_cListPic); pcSlice->checkSTSA(m_cListPic); +#if JVET_R0058 + if (m_pcPic->cs->vps && !m_pcPic->cs->vps->getIndependentLayerFlag(m_pcPic->cs->vps->getGeneralLayerIdx(nalu.m_nuhLayerId)) && m_pcPic->cs->pps->getNumSubPics() > 1) + { + CU::isConformanceILRP(pcSlice); + } +#endif pcSlice->scaleRefPicList( scaledRefPic, m_pcPic->cs->picHeader, m_parameterSetManager.getAPSs(), m_picHeader.getLmcsAPS(), m_picHeader.getScalingListAPS(), true ); diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp index eb7926794a..ce569de6a6 100644 --- a/source/Lib/DecoderLib/DecSlice.cpp +++ b/source/Lib/DecoderLib/DecSlice.cpp @@ -130,7 +130,16 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb DTRACE( g_trace_ctx, D_HEADER, "=========== POC: %d ===========\n", slice->getPOC() ); - +#if JVET_R0058 + if (slice->getSliceType() != I_SLICE && slice->getRefPic(REF_PIC_LIST_0, 0)->cs->pps->getNumSubPics() > 1) + { + clipMv = clipMvInSubpic; + } + else + { + clipMv = clipMvInPic; + } +#endif // for every CTU in the slice segment... unsigned subStrmId = 0; for( unsigned ctuIdx = 0; ctuIdx < slice->getNumCtuInSlice(); ctuIdx++ ) @@ -162,7 +171,11 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb for (int idx = 0; idx < n; idx++) { Picture *refPic = slice->getRefPic((RefPicList)rlist, idx); +#if JVET_R0058 + if (!refPic->getSubPicSaved() && refPic->unscaledPic->cs->pps->getNumSubPics() > 1) +#else if (!refPic->getSubPicSaved()) +#endif { refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight); refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight); diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index f358314bfc..a46112ce0b 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -1370,9 +1370,19 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) READ_FLAG( uiCode, "separate_colour_plane_flag"); CHECK(uiCode != 0, "separate_colour_plane_flag shall be equal to 0"); pcSPS->setSeparateColourPlaneFlag( uiCode != 0 ); } - +#if JVET_R0058 + READ_FLAG(uiCode, "ref_pic_resampling_enabled_flag"); pcSPS->setRprEnabledFlag(uiCode); + if (uiCode) + { + READ_FLAG(uiCode, "res_change_in_clvs_allowed_flag"); pcSPS->setResChangeInClvsEnabledFlag(uiCode); + } + else + { + pcSPS->setResChangeInClvsEnabledFlag(0); + } +#else READ_FLAG( uiCode, "res_change_in_clvs_allowed_flag" ); pcSPS->setRprEnabledFlag( uiCode ); - +#endif if (pcSPS->getProfileTierLevel()->getConstraintInfo()->getNoResChangeInClvsConstraintFlag()) { CHECK(uiCode != 0, "When no_res_change_in_clvs_constraint_flag is equal to 1, res_change_in_clvs_allowed_flag shall be equal to 0"); diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 0913fa106a..4ebd7f2b4b 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -757,7 +757,11 @@ protected: #endif double m_scalingRatioHor; double m_scalingRatioVer; +#if JVET_R0058 + bool m_resChangeInClvsEnabled; +#else bool m_rprEnabled; +#endif int m_switchPocPeriod; int m_upscaledOutput; int m_numRefLayers[MAX_VPS_LAYERS]; @@ -1929,8 +1933,13 @@ public: #endif void setScalingRatio( double hor, double ver ) { m_scalingRatioHor = hor, m_scalingRatioVer = ver; } - void setRPREnabled( bool b ) { m_rprEnabled = b; } +#if JVET_R0058 + void setResChangeInClvsEnabled(bool b) { m_resChangeInClvsEnabled = b; } + bool isResChangeInClvsEnabled() const { return m_resChangeInClvsEnabled; } +#else + void setRPREnabled(bool b) { m_rprEnabled = b; } bool isRPREnabled() const { return m_rprEnabled; } +#endif void setSwitchPocPeriod( int p ) { m_switchPocPeriod = p;} void setUpscaledOutput( int b ) { m_upscaledOutput = b; } int getUpscaledOutput() const { return m_upscaledOutput; } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 2d3c470950..213ff1953b 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -1768,7 +1768,6 @@ void EncGOP::xPicInitLMCS(Picture *pic, PicHeader *picHeader, Slice *slice) if (slice->getSPS()->getUseLmcs()) { const SliceType sliceType = slice->getSliceType(); - m_pcReshaper->getReshapeCW()->rspTid = slice->getTLayer() + (slice->isIntra() ? 0 : 1); m_pcReshaper->getReshapeCW()->rspSliceQP = slice->getSliceQp(); @@ -2164,7 +2163,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, if (pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL0(), 0, false) != 0 || pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL1(), 1, false) != 0 || (m_pcEncLib->getDependentRAPIndicationSEIEnabled() && !pcSlice->isIRAP() && ( pcSlice->isDRAP() || !pcSlice->isPOCInRefPicList(pcSlice->getRPL0(), pcSlice->getAssociatedIRAPPOC())) ) - || ( !pcSlice->isIRAP() && pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers( pcSlice->getPic()->cs->vps->getGeneralLayerIdx( m_pcEncLib->getLayerId() ) ) ) + || (!pcSlice->isIRAP() && pcSlice->getPic()->cs->vps && m_pcEncLib->getNumRefLayers(pcSlice->getPic()->cs->vps->getGeneralLayerIdx(m_pcEncLib->getLayerId()))) ) { xCreateExplicitReferencePictureSetFromReference( pcSlice, rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1() ); @@ -2251,6 +2250,15 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, // Set reference list pcSlice->constructRefPicList(rcListPic); +#if JVET_R0058 + const VPS* vps = pcPic->cs->vps; + int layerIdx = vps == nullptr ? 0 : vps->getGeneralLayerIdx(pcPic->layerId); + if (vps && !vps->getIndependentLayerFlag(layerIdx) && pcPic->cs->pps->getNumSubPics() > 1) + { + CU::isConformanceILRP(pcSlice); + } +#endif + xPicInitHashME( pcPic, pcSlice->getPPS(), rcListPic ); if( m_pcCfg->getUseAMaxBT() ) @@ -2721,6 +2729,19 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, m_pcSliceEncoder->setLosslessSlice(pcPic, isLossless); #endif +#if JVET_R0058 + if (pcSlice->getSliceType() != I_SLICE && pcSlice->getRefPic(REF_PIC_LIST_0, 0)->unscaledPic->cs->pps->getNumSubPics() > 1) + { + clipMv = clipMvInSubpic; + m_pcEncLib->getInterSearch()->setMvClipInSubPic(true); + } + else + { + clipMv = clipMvInPic; + m_pcEncLib->getInterSearch()->setMvClipInSubPic(false); + } +#endif + m_pcSliceEncoder->precompressSlice( pcPic ); m_pcSliceEncoder->compressSlice ( pcPic, false, false ); @@ -3905,7 +3926,11 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni PelStorage upscaledRec; - if( m_pcEncLib->isRPREnabled() ) +#if JVET_R0058 + if (m_pcEncLib->isResChangeInClvsEnabled()) +#else + if (m_pcEncLib->isRPREnabled()) +#endif { const CPelBuf& upscaledOrg = sps.getUseLmcs() ? pcPic->M_BUFS( 0, PIC_TRUE_ORIGINAL_INPUT).get( COMPONENT_Y ) : pcPic->M_BUFS( 0, PIC_ORIGINAL_INPUT).get( COMPONENT_Y ); upscaledRec.create( pic.chromaFormat, Area( Position(), upscaledOrg ) ); @@ -3933,7 +3958,11 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni // when RPR is enabled, picture padding is picture specific due to possible different picture resoluitons, however only full resolution padding is stored in EncLib // get per picture padding from the conformance window, in this case if conformance window is set not equal to the padding then PSNR results may be inaccurate - if( m_pcEncLib->isRPREnabled() ) +#if JVET_R0058 + if (m_pcEncLib->isResChangeInClvsEnabled()) +#else + if (m_pcEncLib->isRPREnabled()) +#endif { Window& conf = pcPic->getConformanceWindow(); padX = conf.getWindowRightOffset() * SPS::getWinUnitX( format ); @@ -3966,7 +3995,11 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni } #endif - if( m_pcEncLib->isRPREnabled() ) +#if JVET_R0058 + if (m_pcEncLib->isResChangeInClvsEnabled()) +#else + if (m_pcEncLib->isRPREnabled()) +#endif { const CPelBuf& upscaledOrg = sps.getUseLmcs() ? pcPic->M_BUFS( 0, PIC_TRUE_ORIGINAL_INPUT ).get( compID ) : pcPic->M_BUFS( 0, PIC_ORIGINAL_INPUT ).get( compID ); @@ -4243,7 +4276,11 @@ void EncGOP::xCalculateAddPSNR(Picture* pcPic, PelUnitBuf cPicD, const AccessUni } msg( NOTICE, "]" ); } - if( m_pcEncLib->isRPREnabled() ) +#if JVET_R0058 + if (m_pcEncLib->isResChangeInClvsEnabled()) +#else + if (m_pcEncLib->isRPREnabled()) +#endif { msg( NOTICE, "\nPSNR2: [Y %6.4lf dB U %6.4lf dB V %6.4lf dB]", upscaledPSNR[COMPONENT_Y], upscaledPSNR[COMPONENT_Cb], upscaledPSNR[COMPONENT_Cr] ); } @@ -5085,7 +5122,10 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL Picture* pic = slice->getPic(); const VPS* vps = slice->getPic()->cs->vps; int layerIdx = vps == nullptr ? 0 : vps->getGeneralLayerIdx( pic->layerId ); - +#if JVET_R0058 + bool isIntraLayerPredAllowed = vps->getIndependentLayerFlag(layerIdx) || (vps->getPredDirection(slice->getTLayer()) != 1); + bool isInterLayerPredAllowed = !vps->getIndependentLayerFlag(layerIdx) && (vps->getPredDirection(slice->getTLayer()) != 2); +#endif ReferencePictureList* pLocalRPL0 = slice->getLocalRPL0(); *pLocalRPL0 = ReferencePictureList( slice->getSPS()->getInterLayerPresentFlag() ); @@ -5095,44 +5135,55 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL uint32_t numOfRefPic = rpl0->getNumberOfShorttermPictures() + rpl0->getNumberOfLongtermPictures(); uint32_t refPicIdxL0 = 0; - for( int ii = 0; ii < numOfRefPic; ii++ ) +#if JVET_R0058 + if (isIntraLayerPredAllowed) { - // loop through all pictures in the reference picture buffer - PicList::iterator iterPic = rcListPic.begin(); - bool isAvailable = false; - - pocCycle = 1 << ( slice->getSPS()->getBitsForPOC() ); - while( iterPic != rcListPic.end() ) +#endif + for (int ii = 0; ii < numOfRefPic; ii++) { - rpcPic = *( iterPic++ ); + // loop through all pictures in the reference picture buffer + PicList::iterator iterPic = rcListPic.begin(); + bool isAvailable = false; - if( rpcPic->layerId == pic->layerId ) + pocCycle = 1 << (slice->getSPS()->getBitsForPOC()); + while (iterPic != rcListPic.end()) { - if( !rpl0->isRefPicLongterm( ii ) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl0->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) ) - { - isAvailable = true; - break; - } - else if( rpl0->isRefPicLongterm( ii ) && rpcPic->referenced && ( rpcPic->getPOC() & ( pocCycle - 1 ) ) == rpl0->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) ) + rpcPic = *(iterPic++); + + if (rpcPic->layerId == pic->layerId) { - isAvailable = true; - break; + if (!rpl0->isRefPicLongterm(ii) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl0->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP)) + { + isAvailable = true; + break; + } + else if (rpl0->isRefPicLongterm(ii) && rpcPic->referenced && (rpcPic->getPOC() & (pocCycle - 1)) == rpl0->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP)) + { + isAvailable = true; + break; + } } } - } - if( isAvailable ) - { - pLocalRPL0->setRefPicIdentifier( refPicIdxL0, rpl0->getRefPicIdentifier( ii ), rpl0->isRefPicLongterm( ii ), false, NOT_VALID ); - refPicIdxL0++; - numOfSTRPL0 = numOfSTRPL0 + ( ( rpl0->isRefPicLongterm( ii ) ) ? 0 : 1 ); - numOfLTRPL0 += ( rpl0->isRefPicLongterm( ii ) && !rpl0->isInterLayerRefPic( ii ) ) ? 1 : 0; - isAvailable = false; + if (isAvailable) + { + pLocalRPL0->setRefPicIdentifier(refPicIdxL0, rpl0->getRefPicIdentifier(ii), rpl0->isRefPicLongterm(ii), false, NOT_VALID); + refPicIdxL0++; + numOfSTRPL0 = numOfSTRPL0 + ((rpl0->isRefPicLongterm(ii)) ? 0 : 1); + numOfLTRPL0 += (rpl0->isRefPicLongterm(ii) && !rpl0->isInterLayerRefPic(ii)) ? 1 : 0; + isAvailable = false; + } } +#if JVET_R0058 } +#endif // inter-layer reference pictures are added to the end of the reference picture list +#if JVET_R0058 + if (layerIdx && vps && !vps->getAllIndependentLayersFlag() && isInterLayerPredAllowed) +#else if( layerIdx && vps && !vps->getAllIndependentLayersFlag() ) +#endif { numOfRefPic = rpl0->getNumberOfInterLayerPictures() ? rpl0->getNumberOfInterLayerPictures() : m_pcEncLib->getNumRefLayers( layerIdx ); @@ -5145,8 +5196,7 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL { rpcPic = *( iterPic++ ); int refLayerIdx = vps->getGeneralLayerIdx( rpcPic->layerId ); - - if( rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag( layerIdx, refLayerIdx ) ) + if (rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag(layerIdx, refLayerIdx)) { pLocalRPL0->setRefPicIdentifier( refPicIdxL0, 0, true, true, vps->getInterLayerRefIdc( layerIdx, refLayerIdx ) ); refPicIdxL0++; @@ -5191,44 +5241,54 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL numOfRefPic = rpl1->getNumberOfShorttermPictures() + rpl1->getNumberOfLongtermPictures(); uint32_t refPicIdxL1 = 0; - for( int ii = 0; ii < numOfRefPic; ii++ ) +#if JVET_R0058 + if (isIntraLayerPredAllowed) { - // loop through all pictures in the reference picture buffer - PicList::iterator iterPic = rcListPic.begin(); - bool isAvailable = false; - pocCycle = 1 << ( slice->getSPS()->getBitsForPOC() ); - while( iterPic != rcListPic.end() ) +#endif + for (int ii = 0; ii < numOfRefPic; ii++) { - rpcPic = *( iterPic++ ); - - if( rpcPic->layerId == pic->layerId ) + // loop through all pictures in the reference picture buffer + PicList::iterator iterPic = rcListPic.begin(); + bool isAvailable = false; + pocCycle = 1 << (slice->getSPS()->getBitsForPOC()); + while (iterPic != rcListPic.end()) { - if( !rpl1->isRefPicLongterm( ii ) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl1->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) ) - { - isAvailable = true; - break; - } - else if( rpl1->isRefPicLongterm( ii ) && rpcPic->referenced && ( rpcPic->getPOC() & ( pocCycle - 1 ) ) == rpl1->getRefPicIdentifier( ii ) && !slice->isPocRestrictedByDRAP( rpcPic->getPOC(), rpcPic->precedingDRAP ) ) + rpcPic = *(iterPic++); + if (rpcPic->layerId == pic->layerId) { - isAvailable = true; - break; + if (!rpl1->isRefPicLongterm(ii) && rpcPic->referenced && rpcPic->getPOC() == slice->getPOC() - rpl1->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP)) + { + isAvailable = true; + break; + } + else if (rpl1->isRefPicLongterm(ii) && rpcPic->referenced && (rpcPic->getPOC() & (pocCycle - 1)) == rpl1->getRefPicIdentifier(ii) && !slice->isPocRestrictedByDRAP(rpcPic->getPOC(), rpcPic->precedingDRAP)) + { + isAvailable = true; + break; + } } } - } - if( isAvailable ) - { - pLocalRPL1->setRefPicIdentifier( refPicIdxL1, rpl1->getRefPicIdentifier( ii ), rpl1->isRefPicLongterm( ii ), false, NOT_VALID ); - refPicIdxL1++; - numOfSTRPL1 = numOfSTRPL1 + ( ( rpl1->isRefPicLongterm( ii ) ) ? 0 : 1 ); - numOfLTRPL1 += ( rpl1->isRefPicLongterm( ii ) && !rpl1->isInterLayerRefPic( ii ) ) ? 1 : 0; - isAvailable = false; + if (isAvailable) + { + pLocalRPL1->setRefPicIdentifier(refPicIdxL1, rpl1->getRefPicIdentifier(ii), rpl1->isRefPicLongterm(ii), false, NOT_VALID); + refPicIdxL1++; + numOfSTRPL1 = numOfSTRPL1 + ((rpl1->isRefPicLongterm(ii)) ? 0 : 1); + numOfLTRPL1 += (rpl1->isRefPicLongterm(ii) && !rpl1->isInterLayerRefPic(ii)) ? 1 : 0; + isAvailable = false; + } } +#if JVET_R0058 } +#endif // inter-layer reference pictures are added to the end of the reference picture list +#if JVET_R0058 + if (layerIdx && vps && !vps->getAllIndependentLayersFlag() && isInterLayerPredAllowed) +#else if( layerIdx && vps && !vps->getAllIndependentLayersFlag() ) +#endif { numOfRefPic = rpl1->getNumberOfInterLayerPictures() ? rpl1->getNumberOfInterLayerPictures() : m_pcEncLib->getNumRefLayers( layerIdx ); @@ -5241,8 +5301,7 @@ void EncGOP::xCreateExplicitReferencePictureSetFromReference( Slice* slice, PicL { rpcPic = *( iterPic++ ); int refLayerIdx = vps->getGeneralLayerIdx( rpcPic->layerId ); - - if( rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag( layerIdx, refLayerIdx ) ) + if (rpcPic->referenced && rpcPic->getPOC() == pic->getPOC() && vps->getDirectRefLayerFlag(layerIdx, refLayerIdx)) { pLocalRPL1->setRefPicIdentifier( refPicIdxL1, 0, true, true, vps->getInterLayerRefIdc( layerIdx, refLayerIdx ) ); refPicIdxL1++; diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 6f8c06a57d..a7f0cb9466 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -260,7 +260,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) // initialize APS xInitRPL(sps0, isFieldCoding); - if( m_rprEnabled ) +#if JVET_R0058 + if (m_resChangeInClvsEnabled) +#else + if (m_rprEnabled) +#endif { PPS &pps = *( m_ppsMap.allocatePS( ENC_PPS_ID_RPR ) ); Window& inputScalingWindow = pps0.getScalingWindow(); @@ -443,7 +447,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) { xInitScalingLists( sps0, aps0 ); } - if( m_rprEnabled ) +#if JVET_R0058 + if (m_resChangeInClvsEnabled) +#else + if (m_rprEnabled) +#endif { xInitScalingLists( sps0, *m_apsMap.getPS( ENC_PPS_ID_RPR ) ); } @@ -624,8 +632,11 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu ppsID += ( getSwitchPOC() != -1 && ( m_iPOCLast + 1 >= getSwitchPOC() ) ? 1 : 0 ); } #endif - +#if JVET_R0058 + if( m_resChangeInClvsEnabled && m_intraPeriod == -1 ) +#else if( m_rprEnabled && m_intraPeriod == -1 ) +#endif { const int poc = m_iPOCLast + ( m_compositeRefEnabled ? 2 : 1 ); @@ -649,7 +660,11 @@ bool EncLib::encodePrep( bool flush, PelStorage* pcPicYuvOrg, PelStorage* cPicYu const PPS *pPPS = ( ppsID < 0 ) ? m_ppsMap.getFirstPS() : m_ppsMap.getPS( ppsID ); const SPS *pSPS = m_spsMap.getPS( pPPS->getSPSId() ); - if( m_rprEnabled ) +#if JVET_R0058 + if (m_resChangeInClvsEnabled) +#else + if (m_rprEnabled) +#endif { pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Y ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Y ) ); pcPicCurr->M_BUFS( 0, PIC_ORIGINAL_INPUT ).getBuf( COMPONENT_Cb ).copyFrom( pcPicYuvOrg->getBuf( COMPONENT_Cb ) ); @@ -944,7 +959,11 @@ void EncLib::xGetNewPicBuffer ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Pict { rpcPic = new Picture; rpcPic->create( sps.getChromaFormatIdc(), Size( pps.getPicWidthInLumaSamples(), pps.getPicHeightInLumaSamples() ), sps.getMaxCUWidth(), sps.getMaxCUWidth() + 16, false, m_layerId ); - if( m_rprEnabled ) +#if JVET_R0058 + if (m_resChangeInClvsEnabled) +#else + if (m_rprEnabled) +#endif { const PPS &pps0 = *m_ppsMap.getPS(0); rpcPic->M_BUFS(0, PIC_ORIGINAL_INPUT).create(sps.getChromaFormatIdc(), Area(Position(), Size(pps0.getPicWidthInLumaSamples(), pps0.getPicHeightInLumaSamples()))); @@ -1156,7 +1175,11 @@ void EncLib::xInitSPS( SPS& sps ) sps.setVPSId( m_vps->getVPSId() ); sps.setMaxPicWidthInLumaSamples( m_iSourceWidth ); sps.setMaxPicHeightInLumaSamples( m_iSourceHeight ); +#if JVET_R0058 + if (m_resChangeInClvsEnabled) +#else if (m_rprEnabled) +#endif { int maxPicWidth = std::max(m_iSourceWidth, (int)((double)m_iSourceWidth / m_scalingRatioHor + 0.5)); int maxPicHeight = std::max(m_iSourceHeight, (int)((double)m_iSourceHeight / m_scalingRatioVer + 0.5)); @@ -1423,12 +1446,20 @@ void EncLib::xInitSPS( SPS& sps ) sps.setInterLayerPresentFlag( m_layerId > 0 && m_vps->getMaxLayers() > 1 && !m_vps->getAllIndependentLayersFlag() && !m_vps->getIndependentLayerFlag( m_vps->getGeneralLayerIdx( m_layerId ) ) ); CHECK( m_vps->getIndependentLayerFlag( m_vps->getGeneralLayerIdx( m_layerId ) ) && sps.getInterLayerPresentFlag(), " When vps_independent_layer_flag[GeneralLayerIdx[nuh_layer_id ]] is equal to 1, the value of inter_layer_ref_pics_present_flag shall be equal to 0." ); - - sps.setRprEnabledFlag( m_rprEnabled || sps.getInterLayerPresentFlag() ); +#if JVET_R0058 + sps.setResChangeInClvsEnabledFlag(m_resChangeInClvsEnabled); + sps.setRprEnabledFlag((m_resChangeInClvsEnabled) || sps.getInterLayerPresentFlag()); +#else + sps.setRprEnabledFlag(m_rprEnabled || sps.getInterLayerPresentFlag()); +#endif sps.setLog2ParallelMergeLevelMinus2( m_log2ParallelMergeLevelMinus2 ); - CHECK( sps.getRprEnabledFlag() && sps.getVirtualBoundariesEnabledFlag(), "when the value of res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0" ); +#if JVET_R0058 + CHECK(sps.getResChangeInClvsEnabledFlag() && sps.getVirtualBoundariesEnabledFlag(), "when the value of res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0"); +#else + CHECK(sps.getRprEnabledFlag() && sps.getVirtualBoundariesEnabledFlag(), "when the value of res_change_in_clvs_allowed_flag is equal to 1, the value of sps_virtual_boundaries_present_flag shall be equal to 0"); +#endif } void EncLib::xInitHrdParameters(SPS &sps) diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h index 3a2e28cd41..f75c629b57 100644 --- a/source/Lib/EncoderLib/EncLib.h +++ b/source/Lib/EncoderLib/EncLib.h @@ -282,8 +282,11 @@ public: std::list<PelUnitBuf*>& rcListPicYuvRecOut, int& iNumEncoded, bool isTff ); - - void printSummary( bool isField ) { m_cGOPEncoder.printOutSummary( m_uiNumAllPicCoded, isField, m_printMSEBasedSequencePSNR, m_printSequenceMSE, m_printHexPsnr, m_rprEnabled, m_spsMap.getFirstPS()->getBitDepths() ); } +#if JVET_R0058 + void printSummary(bool isField) { m_cGOPEncoder.printOutSummary(m_uiNumAllPicCoded, isField, m_printMSEBasedSequencePSNR, m_printSequenceMSE, m_printHexPsnr, m_resChangeInClvsEnabled, m_spsMap.getFirstPS()->getBitDepths()); } +#else + void printSummary(bool isField) { m_cGOPEncoder.printOutSummary(m_uiNumAllPicCoded, isField, m_printMSEBasedSequencePSNR, m_printSequenceMSE, m_printHexPsnr, m_rprEnabled, m_spsMap.getFirstPS()->getBitDepths()); } +#endif int getLayerId() const { return m_layerId; } VPS* getVPS() { return m_vps; } diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index c821cdbe78..fd0537a84d 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -430,7 +430,6 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr // slice type SliceType eSliceType; - eSliceType=B_SLICE; if (m_pcCfg->getIntraPeriod() > 0 ) { @@ -1379,7 +1378,6 @@ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, c } } #endif // ENABLE_QPA - bool checkPLTRatio = m_pcCfg->getIntraPeriod() != 1 && pcSlice->isIRAP(); if (checkPLTRatio) { @@ -1566,7 +1564,11 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons for (int idx = 0; idx < n; idx++) { Picture *refPic = pcSlice->getRefPic((RefPicList)rlist, idx); +#if JVET_R0058 + if (!refPic->getSubPicSaved() && refPic->unscaledPic->cs->pps->getNumSubPics() > 1) +#else if (!refPic->getSubPicSaved()) +#endif { refPic->saveSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight); refPic->extendSubPicBorder(refPic->getPOC(), subPicX, subPicY, subPicWidth, subPicHeight); diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp index fa8fc9e99d..4c3a8ee33c 100644 --- a/source/Lib/EncoderLib/InterSearch.cpp +++ b/source/Lib/EncoderLib/InterSearch.cpp @@ -1408,6 +1408,10 @@ void InterSearch::xSetIntraSearchRange(PredictionUnit& pu, int iRoiWidth, int iR rcMvSrchRngLT <<= 2; rcMvSrchRngRB <<= 2; +#if JVET_R0058 + bool temp = m_bMvClipInSubPic; + m_bMvClipInSubPic = true; +#endif xClipMv(rcMvSrchRngLT, pu.cu->lumaPos(), pu.cu->lumaSize(), sps @@ -1418,6 +1422,9 @@ void InterSearch::xSetIntraSearchRange(PredictionUnit& pu, int iRoiWidth, int iR sps , *pu.cs->pps ); +#if JVET_R0058 + m_bMvClipInSubPic = temp; +#endif rcMvSrchRngLT >>= 2; rcMvSrchRngRB >>= 2; } @@ -3253,6 +3260,7 @@ Distortion InterSearch::xGetTemplateCost( const PredictionUnit& pu, const Picture* picRef = pu.cu->slice->getRefPic( eRefPicList, iRefIdx ); clipMv( cMvCand, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps ); + // prediction pattern const bool bi = pu.cu->slice->testWeightPred() && pu.cu->slice->getSliceType()==P_SLICE; @@ -3397,6 +3405,7 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref Mv bestInitMv = (bBi ? rcMv : rcMvPred); Mv cTmpMv = bestInitMv; + clipMv( cTmpMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps ); cTmpMv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_INT); m_cDistParam.cur.buf = cStruct.piRefY + (cTmpMv.ver * cStruct.iRefStride) + cTmpMv.hor; @@ -3436,9 +3445,7 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref if( !bQTBTMV ) { - xSetSearchRange(pu, bestInitMv, iSrchRng, cStruct.searchRange - , cStruct - ); + xSetSearchRange(pu, bestInitMv, iSrchRng, cStruct.searchRange, cStruct); } xPatternSearch( cStruct, rcMv, ruiCost); } @@ -3503,7 +3510,6 @@ void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, Ref } - void InterSearch::xSetSearchRange ( const PredictionUnit& pu, const Mv& cMvPred, const int iSrchRng, @@ -3514,7 +3520,6 @@ void InterSearch::xSetSearchRange ( const PredictionUnit& pu, const int iMvShift = MV_FRACTIONAL_BITS_INTERNAL; Mv cFPMvPred = cMvPred; clipMv( cFPMvPred, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps ); - Mv mvTL(cFPMvPred.getHor() - (iSrchRng << iMvShift), cFPMvPred.getVer() - (iSrchRng << iMvShift)); Mv mvBR(cFPMvPred.getHor() + (iSrchRng << iMvShift), cFPMvPred.getVer() + (iSrchRng << iMvShift)); @@ -3778,9 +3783,7 @@ void InterSearch::xTZSearch( const PredictionUnit& pu, // set search range Mv currBestMv(cStruct.iBestX, cStruct.iBestY ); currBestMv <<= MV_FRACTIONAL_BITS_INTERNAL; - xSetSearchRange(pu, currBestMv, m_iSearchRange >> (bFastSettings ? 1 : 0), sr - , cStruct - ); + xSetSearchRange(pu, currBestMv, m_iSearchRange >> (bFastSettings ? 1 : 0), sr, cStruct); } if (m_pcEncCfg->getUseHashME() && (m_currRefPicList == 0 || pu.cu->slice->getList1IdxToList0Idx(m_currRefPicIndex) < 0)) { @@ -4012,6 +4015,7 @@ void InterSearch::xTZSearchSelective( const PredictionUnit& pu, int iStartX = 0; int iStartY = 0; int iDist = 0; + clipMv( rcMv, pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps ); rcMv.changePrecision(MV_PRECISION_INTERNAL, MV_PRECISION_QUARTER); rcMv.divideByPowerOf2(2); @@ -4084,9 +4088,7 @@ void InterSearch::xTZSearchSelective( const PredictionUnit& pu, // set search range Mv currBestMv(cStruct.iBestX, cStruct.iBestY ); currBestMv <<= 2; - xSetSearchRange( pu, currBestMv, m_iSearchRange, sr - , cStruct - ); + xSetSearchRange( pu, currBestMv, m_iSearchRange, sr, cStruct ); } if (m_pcEncCfg->getUseHashME() && (m_currRefPicList == 0 || pu.cu->slice->getList1IdxToList0Idx(m_currRefPicIndex) < 0)) { @@ -5756,7 +5758,6 @@ void InterSearch::xAffineMotionEstimation( PredictionUnit& pu, acMvTemp[j].set(centerMv[j].getHor() + (testPos[i][0] << mvShift), centerMv[j].getVer() + (testPos[i][1] << mvShift)); clipMv( acMvTemp[j], pu.cu->lumaPos(), pu.cu->lumaSize(), *pu.cs->sps, *pu.cs->pps ); xPredAffineBlk(COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cu->slice->clpRng(COMPONENT_Y)); - Distortion costTemp = m_pcRdCost->getDistPart(predBuf.Y(), pBuf->Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, distFunc); uint32_t bitsTemp = ruiBits; bitsTemp += xCalcAffineMVBits(pu, acMvTemp, acMvPred); @@ -7789,7 +7790,11 @@ void InterSearch::xClipMv( Mv& rcMv, const Position& pos, const struct Size& siz int verMax = ( pps.getPicHeightInLumaSamples() + offset - (int)pos.y - 1 ) << mvShift; int verMin = ( -( int ) sps.getMaxCUHeight() - offset - ( int ) pos.y + 1 ) << mvShift; const SubPic &curSubPic = pps.getSubPicFromPos(pos); +#if JVET_R0058 + if (curSubPic.getTreatedAsPicFlag() && m_bMvClipInSubPic) +#else if (curSubPic.getTreatedAsPicFlag()) +#endif { horMax = ((curSubPic.getSubPicRight() + 1) + offset - (int)pos.x - 1) << mvShift; horMin = (-(int)sps.getMaxCUWidth() - offset - ((int)pos.x - curSubPic.getSubPicLeft()) + 1) << mvShift; diff --git a/source/Lib/EncoderLib/InterSearch.h b/source/Lib/EncoderLib/InterSearch.h index 126832e4bb..80eb1fab9d 100644 --- a/source/Lib/EncoderLib/InterSearch.h +++ b/source/Lib/EncoderLib/InterSearch.h @@ -172,6 +172,9 @@ protected: bool m_skipSbtAll; // to skip all SBT modes for the current PU uint8_t m_histBestSbt; // historical best SBT mode for PU of certain SSE values uint8_t m_histBestMtsIdx; // historical best MTS idx for PU of certain SSE values +#if JVET_R0058 + bool m_bMvClipInSubPic; +#endif public: InterSearch(); @@ -317,6 +320,9 @@ public: void resetSavedAffineMotion(); void storeAffineMotion( Mv acAffineMv[2][3], int16_t affineRefIdx[2], EAffineModel affineType, int bcwIdx ); bool searchBv(PredictionUnit& pu, int xPos, int yPos, int width, int height, int picWidth, int picHeight, int xBv, int yBv, int ctuSize); +#if JVET_R0058 + void setMvClipInSubPic(bool bFlag) { m_bMvClipInSubPic = bFlag; } +#endif protected: /// sub-function for motion vector refinement used in fractional-pel accuracy diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index b03c45c8d1..457013878a 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -847,9 +847,15 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) } const uint32_t chromaArrayType = separate_colour_plane_flag ? 0 : format; - +#if JVET_R0058 + WRITE_FLAG(pcSPS->getRprEnabledFlag(), "ref_pic_resampling_enabled_flag"); + if (pcSPS->getRprEnabledFlag()) + { + WRITE_FLAG(pcSPS->getResChangeInClvsEnabledFlag(), "res_change_in_clvs_allowed_flag"); + } +#else WRITE_FLAG( pcSPS->getRprEnabledFlag(), "res_change_in_clvs_allowed_flag" ); - +#endif WRITE_UVLC( pcSPS->getMaxPicWidthInLumaSamples(), "pic_width_max_in_luma_samples" ); WRITE_UVLC( pcSPS->getMaxPicHeightInLumaSamples(), "pic_height_max_in_luma_samples" ); Window conf = pcSPS->getConformanceWindow(); @@ -920,7 +926,6 @@ 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 -- GitLab