diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 44f5c61e5fc18f7ece0abecb1f1f13cc3fc28ff3..05a0422fcf65793277ca6d8a62c7326c03519013 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -1991,6 +1991,9 @@ SPS::SPS() ::memset(m_usedByCurrPicLtSPSFlag, 0, sizeof(m_usedByCurrPicLtSPSFlag)); ::memset(m_virtualBoundariesPosX, 0, sizeof(m_virtualBoundariesPosX)); ::memset(m_virtualBoundariesPosY, 0, sizeof(m_virtualBoundariesPosY)); +#if JVET_Q0179_SCALING_WINDOW_SIZE_CONSTRAINT + ::memset(m_ppsValidFlag, 0, sizeof(m_ppsValidFlag)); +#endif } SPS::~SPS() diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index a92277563564698c04406dbc264ebe5b558cb0e4..cd71ed5b562a44ee3440e8541c448700ea873fa5 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1236,6 +1236,10 @@ private: #if JVET_Q0297_MER uint32_t m_log2ParallelMergeLevelMinus2; #endif +#if JVET_Q0179_SCALING_WINDOW_SIZE_CONSTRAINT + bool m_ppsValidFlag[64]; + Size m_scalingWindowSizeInPPS[64]; +#endif public: @@ -1563,6 +1567,12 @@ void setCCALFEnabledFlag( bool b ) uint32_t getLog2ParallelMergeLevelMinus2() const { return m_log2ParallelMergeLevelMinus2; } void setLog2ParallelMergeLevelMinus2(uint32_t mrgLevel) { m_log2ParallelMergeLevelMinus2 = mrgLevel; } #endif +#if JVET_Q0179_SCALING_WINDOW_SIZE_CONSTRAINT + void setPPSValidFlag(int i, bool b) { m_ppsValidFlag[i] = b; } + bool getPPSValidFlag(int i) { return m_ppsValidFlag[i]; } + void setScalingWindowSizeInPPS(int i, int scWidth, int scHeight) { m_scalingWindowSizeInPPS[i].width = scWidth; m_scalingWindowSizeInPPS[i].height = scHeight; } + const Size& getScalingWindowSizeInPPS(int i) { return m_scalingWindowSizeInPPS[i]; } +#endif }; diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 355a954d9044c86cdf7e7ac139e19ca2e0df83ce..727f15fafa758133449508186c38ca00229facbe 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_Q0179_SCALING_WINDOW_SIZE_CONSTRAINT 1 // JVET-Q0179: Scaling window size constraint for constraining worst case memory bandwidth + #define JVET_Q0420_PPS_CHROMA_TOOL_FLAG 1 // JVET-Q0420: add pps_chroma_tool_offsets_present_flag in PPS #define JVET_Q0172_CHROMA_FORMAT_BITDEPTH_CONSTRAINT 1 //JVET-Q0172: Disallow differing chroma format and different bit depths for cross-layer prediction. diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 023d7796ff3031589b699c6a4c8802704d713b12..012adc05dbc62ac07e7aa68d25a7cfb8a76bafea 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -123,6 +123,17 @@ bool CU::getRprScaling( const SPS* sps, const PPS* curPPS, Picture* refPic, int& xScale = ( ( refPicWidth << SCALE_RATIO_BITS ) + ( curPicWidth >> 1 ) ) / curPicWidth; yScale = ( ( refPicHeight << SCALE_RATIO_BITS ) + ( curPicHeight >> 1 ) ) / curPicHeight; +#if JVET_Q0179_SCALING_WINDOW_SIZE_CONSTRAINT + int curSeqMaxPicWidthY = sps->getMaxPicWidthInLumaSamples(); // pic_width_max_in_luma_samples + int curSeqMaxPicHeightY = sps->getMaxPicHeightInLumaSamples(); // pic_height_max_in_luma_samples + int curPicWidthY = curPPS->getPicWidthInLumaSamples(); // pic_width_in_luma_samples + int curPicHeightY = curPPS->getPicHeightInLumaSamples(); // pic_height_in_luma_samples + int max8MinCbSizeY = std::max((int)8, (1<<sps->getLog2MinCodingBlockSize())); // Max(8, MinCbSizeY) + + CHECK((curPicWidth * curSeqMaxPicWidthY) < refPicWidth * (curPicWidthY - max8MinCbSizeY), "(curPicWidth * curSeqMaxPicWidthY) should be greater than or equal to refPicWidth * (curPicWidthY - max8MinCbSizeY))"); + CHECK((curPicHeight * curSeqMaxPicHeightY) < refPicHeight * (curPicHeightY - max8MinCbSizeY), "(curPicHeight * curSeqMaxPicHeightY) should be greater than or equal to refPicHeight * (curPicHeightY - max8MinCbSizeY))"); +#endif + #if JVET_Q0487_SCALING_WINDOW_ISSUES return refPic->isRefScaled( curPPS ); #else diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index da6e357013ac3c10028981e362acb384653d84fb..e46c6fcc463851ee79c0fde4a3820a08689cb60a 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -317,6 +317,31 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) scalingWindow.setWindow( 0, width - scaledWidth, 0, height - scaledHeight ); pps.setScalingWindow( scalingWindow ); +#if JVET_Q0179_SCALING_WINDOW_SIZE_CONSTRAINT + //register the width/height of the current pic into reference SPS + if (!sps0.getPPSValidFlag(pps.getPPSId())) + { + sps0.setPPSValidFlag(pps.getPPSId(), true); + sps0.setScalingWindowSizeInPPS(pps.getPPSId(), scaledWidth, scaledHeight); + } + int curSeqMaxPicWidthY = sps0.getMaxPicWidthInLumaSamples(); // pic_width_max_in_luma_samples + int curSeqMaxPicHeightY = sps0.getMaxPicHeightInLumaSamples(); // pic_height_max_in_luma_samples + int curPicWidthY = width; // pic_width_in_luma_samples + int curPicHeightY = height; // pic_height_in_luma_samples + int max8MinCbSizeY = std::max((int)8, (1 << sps0.getLog2MinCodingBlockSize())); // Max(8, MinCbSizeY) + //Warning message of potential scaling window size violation + for (int i = 0; i < 64; i++) + { + if (sps0.getPPSValidFlag(i)) + { + if ((scaledWidth * curSeqMaxPicWidthY) < sps0.getScalingWindowSizeInPPS(i).width * (curPicWidthY - max8MinCbSizeY)) + printf("Potential violation: (curScaledWIdth * curSeqMaxPicWidthY) should be greater than or equal to refScaledWidth * (curPicWidthY - max(8, MinCbSizeY)\n"); + if ((scaledHeight * curSeqMaxPicHeightY) < sps0.getScalingWindowSizeInPPS(i).height * (curPicHeightY - max8MinCbSizeY)) + printf("Potential violation: (curScaledHeight * curSeqMaxPicHeightY) should be greater than or equal to refScaledHeight * (curPicHeightY - max(8, MinCbSizeY)\n"); + } + } +#endif + // disable picture partitioning for scaled RPR pictures (slice/tile config only provided for the original resolution) m_noPicPartitionFlag = true;