diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp index 52ca3e3ca2890df0f22120417b6cb35c23ff6b1b..3d622fdb50bf66908d3c26f681e8b581d5f08481 100644 --- a/source/Lib/CommonLib/InterPrediction.cpp +++ b/source/Lib/CommonLib/InterPrediction.cpp @@ -2349,6 +2349,33 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio, int refPicWidth = refPic->cs->pps->getPicWidthInLumaSamples(); int refPicHeight = refPic->cs->pps->getPicHeightInLumaSamples(); +#if JVET_P0088_P0353_RPR_FILTERS + int xFilter = filterIndex; + int yFilter = filterIndex; + const int rprThreshold1 = ( 1 << SCALE_RATIO_BITS ) * 5 / 4; + const int rprThreshold2 = ( 1 << SCALE_RATIO_BITS ) * 7 / 4; + if( filterIndex == 0 ) + { + if( scalingRatio.first > rprThreshold2 ) + { + xFilter = 4; + } + else if( scalingRatio.first > rprThreshold1 ) + { + xFilter = 3; + } + + if( scalingRatio.second > rprThreshold2 ) + { + yFilter = 4; + } + else if( scalingRatio.second > rprThreshold1 ) + { + yFilter = 3; + } + } +#endif + const int posShift = SCALE_RATIO_BITS - 4; int stepX = ( scalingRatio.first + 8 ) >> 4; int stepY = ( scalingRatio.second + 8 ) >> 4; @@ -2397,7 +2424,11 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio, refBuf = refPic->getRecoBuf( CompArea( compID, chFmt, offset, Size( 1, refHeight ) ), wrapRef ); Pel* tempBuf = buffer + col; +#if JVET_P0088_P0353_RPR_FILTERS + m_if.filterHor( compID, (Pel*)refBuf.buf - ( ( vFilterSize >> 1 ) - 1 ) * refBuf.stride, refBuf.stride, tempBuf, tmpStride, 1, refHeight + vFilterSize - 1 + extSize, xFrac, false, chFmt, clpRng, xFilter, false, useAltHpelIf ); +#else m_if.filterHor( compID, (Pel*)refBuf.buf - ( ( vFilterSize >> 1 ) - 1 ) * refBuf.stride, refBuf.stride, tempBuf, tmpStride, 1, refHeight + vFilterSize - 1 + extSize, xFrac, false, chFmt, clpRng, filterIndex, false, useAltHpelIf ); +#endif } for( row = 0; row < height; row++ ) @@ -2412,7 +2443,11 @@ bool InterPrediction::xPredInterBlkRPR( const std::pair<int, int>& scalingRatio, Pel* tempBuf = buffer + ( yInt - yInt0 ) * tmpStride; JVET_J0090_SET_CACHE_ENABLE( false ); +#if JVET_P0088_P0353_RPR_FILTERS + m_if.filterVer( compID, tempBuf + ( ( vFilterSize >> 1 ) - 1 ) * tmpStride, tmpStride, dst + row * dstStride, dstStride, width, 1, yFrac, false, rndRes, chFmt, clpRng, yFilter, false, useAltHpelIf ); +#else m_if.filterVer( compID, tempBuf + ( ( vFilterSize >> 1 ) - 1 ) * tmpStride, tmpStride, dst + row * dstStride, dstStride, width, 1, yFrac, false, rndRes, chFmt, clpRng, filterIndex, false, useAltHpelIf ); +#endif JVET_J0090_SET_CACHE_ENABLE( true ); } diff --git a/source/Lib/CommonLib/InterpolationFilter.cpp b/source/Lib/CommonLib/InterpolationFilter.cpp index 1b0a09738af87c7ae5ee3df93342434857f1d6fe..f7115296e953bb600ed0f780c7b885361b15d30e 100644 --- a/source/Lib/CommonLib/InterpolationFilter.cpp +++ b/source/Lib/CommonLib/InterpolationFilter.cpp @@ -94,6 +94,50 @@ const TFilterCoeff InterpolationFilter::m_lumaFilter[LUMA_INTERPOLATION_FILTER_S { 0, 1, -2, 4, 63, -3, 1, 0 } }; +#if JVET_P0088_P0353_RPR_FILTERS +// 1.5x +const TFilterCoeff InterpolationFilter::m_lumaFilterRPR1[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_LUMA] = +{ + { -1, -5, 17, 42, 17, -5, -1, 0 }, + { 0, -5, 15, 41, 19, -5, -1, 0 }, + { 0, -5, 13, 40, 21, -4, -1, 0 }, + { 0, -5, 11, 39, 24, -4, -2, 1 }, + { 0, -5, 9, 38, 26, -3, -2, 1 }, + { 0, -5, 7, 38, 28, -2, -3, 1 }, + { 1, -5, 5, 36, 30, -1, -3, 1 }, + { 1, -4, 3, 35, 32, 0, -4, 1 }, + { 1, -4, 2, 33, 33, 2, -4, 1 }, + { 1, -4, 0, 32, 35, 3, -4, 1 }, + { 1, -3, -1, 30, 36, 5, -5, 1 }, + { 1, -3, -2, 28, 38, 7, -5, 0 }, + { 1, -2, -3, 26, 38, 9, -5, 0 }, + { 1, -2, -4, 24, 39, 11, -5, 0 }, + { 0, -1, -4, 21, 40, 13, -5, 0 }, + { 0, -1, -5, 19, 41, 15, -5, 0 } +}; + +// 2x +const TFilterCoeff InterpolationFilter::m_lumaFilterRPR2[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_LUMA] = +{ + { -4, 2, 20, 28, 20, 2, -4, 0 }, + { -4, 0, 19, 29, 21, 5, -4, -2 }, + { -4, -1, 18, 29, 22, 6, -4, -2 }, + { -4, -1, 16, 29, 23, 7, -4, -2 }, + { -4, -1, 16, 28, 24, 7, -4, -2 }, + { -4, -1, 14, 28, 25, 8, -4, -2 }, + { -3, -3, 14, 27, 26, 9, -3, -3 }, + { -3, -1, 12, 28, 25, 10, -4, -3 }, + { -3, -3, 11, 27, 27, 11, -3, -3 }, + { -3, -4, 10, 25, 28, 12, -1, -3 }, + { -3, -3, 9, 26, 27, 14, -3, -3 }, + { -2, -4, 8, 25, 28, 14, -1, -4 }, + { -2, -4, 7, 24, 28, 16, -1, -4 }, + { -2, -4, 7, 23, 29, 16, -1, -4 }, + { -2, -4, 6, 22, 29, 18, -1, -4 }, + { -2, -4, 5, 21, 29, 19, 0, -4 } +}; +#endif + const TFilterCoeff InterpolationFilter::m_lumaAltHpelIFilter[NTAPS_LUMA] = { 0, 3, 9, 20, 20, 9, 3, 0 }; const TFilterCoeff InterpolationFilter::m_chromaFilter[CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_CHROMA] = { @@ -131,6 +175,82 @@ const TFilterCoeff InterpolationFilter::m_chromaFilter[CHROMA_INTERPOLATION_FILT { 0, 2, 63, -1 }, }; +#if JVET_P0088_P0353_RPR_FILTERS +//1.5x +const TFilterCoeff InterpolationFilter::m_chromaFilterRPR1[CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_CHROMA] = +{ + { 12, 40, 12, 0 }, + { 11, 40, 13, 0 }, + { 10, 40, 15, -1 }, + { 9, 40, 16, -1 }, + { 8, 40, 17, -1 }, + { 8, 39, 18, -1 }, + { 7, 39, 19, -1 }, + { 6, 38, 21, -1 }, + { 5, 38, 22, -1 }, + { 4, 38, 23, -1 }, + { 4, 37, 24, -1 }, + { 3, 36, 25, 0 }, + { 3, 35, 26, 0 }, + { 2, 34, 28, 0 }, + { 2, 33, 29, 0 }, + { 1, 33, 30, 0 }, + { 1, 31, 31, 1 }, + { 0, 30, 33, 1 }, + { 0, 29, 33, 2 }, + { 0, 28, 34, 2 }, + { 0, 26, 35, 3 }, + { 0, 25, 36, 3 }, + { -1, 24, 37, 4 }, + { -1, 23, 38, 4 }, + { -1, 22, 38, 5 }, + { -1, 21, 38, 6 }, + { -1, 19, 39, 7 }, + { -1, 18, 39, 8 }, + { -1, 17, 40, 8 }, + { -1, 16, 40, 9 }, + { -1, 15, 40, 10 }, + { 0, 13, 40, 11 }, +}; + +//2x +const TFilterCoeff InterpolationFilter::m_chromaFilterRPR2[CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_CHROMA] = +{ + { 17, 30, 17, 0 }, + { 17, 30, 18, -1 }, + { 16, 30, 18, 0 }, + { 16, 30, 18, 0 }, + { 15, 30, 18, 1 }, + { 14, 30, 18, 2 }, + { 13, 29, 19, 3 }, + { 13, 29, 19, 3 }, + { 12, 29, 20, 3 }, + { 11, 28, 21, 4 }, + { 10, 28, 22, 4 }, + { 10, 27, 22, 5 }, + { 9, 27, 23, 5 }, + { 9, 26, 24, 5 }, + { 8, 26, 24, 6 }, + { 7, 26, 25, 6 }, + { 7, 25, 25, 7 }, + { 6, 25, 26, 7 }, + { 6, 24, 26, 8 }, + { 5, 24, 26, 9 }, + { 5, 23, 27, 9 }, + { 5, 22, 27, 10 }, + { 4, 22, 28, 10 }, + { 4, 21, 28, 11 }, + { 3, 20, 29, 12 }, + { 3, 19, 29, 13 }, + { 3, 19, 29, 13 }, + { 2, 18, 30, 14 }, + { 1, 18, 30, 15 }, + { 0, 18, 30, 16 }, + { 0, 18, 30, 16 }, + { -1, 18, 30, 17 } +}; +#endif + const TFilterCoeff InterpolationFilter::m_bilinearFilter[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_BILINEAR] = { { 64, 0, }, @@ -578,45 +698,69 @@ void InterpolationFilter::filterVer(const ClpRng& clpRng, Pel const *src, int sr */ void InterpolationFilter::filterHor(const ComponentID compID, Pel const *src, int srcStride, Pel *dst, int dstStride, int width, int height, int frac, bool isLast, const ChromaFormat fmt, const ClpRng& clpRng, int nFilterIdx, bool biMCForDMVR, bool useAltHpelIf) { +#if JVET_P0088_P0353_RPR_FILTERS + if( frac == 0 && nFilterIdx < 2 ) +#else if( frac == 0 ) +#endif { - m_filterCopy[true][isLast](clpRng, src, srcStride, dst, dstStride, width, height, biMCForDMVR); + m_filterCopy[true][isLast]( clpRng, src, srcStride, dst, dstStride, width, height, biMCForDMVR ); } else if( isLuma( compID ) ) { CHECK( frac < 0 || frac >= LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS, "Invalid fraction" ); if( nFilterIdx == 1 ) { - filterHor<NTAPS_BILINEAR>(clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_bilinearFilterPrec4[frac], biMCForDMVR); + filterHor<NTAPS_BILINEAR>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_bilinearFilterPrec4[frac], biMCForDMVR ); } else if( nFilterIdx == 2 ) { filterHor<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_lumaFilter4x4[frac], biMCForDMVR ); } +#if JVET_P0088_P0353_RPR_FILTERS + else if( nFilterIdx == 3 ) + { + filterHor<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_lumaFilterRPR1[frac], biMCForDMVR ); + } + else if( nFilterIdx == 4 ) + { + filterHor<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_lumaFilterRPR2[frac], biMCForDMVR ); + } +#endif + else if( frac == 8 && useAltHpelIf ) + { + filterHor<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_lumaAltHpelIFilter, biMCForDMVR ); + } + else if( ( width == 4 && height == 4 ) || ( width == 4 && height == ( 4 + NTAPS_LUMA - 1 ) ) ) + { + filterHor<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_lumaFilter4x4[frac], biMCForDMVR ); + } else { - if (frac == 8 && useAltHpelIf) - { - filterHor<NTAPS_LUMA>(clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_lumaAltHpelIFilter, biMCForDMVR); - } - else - { - if ((width == 4 && height == 4) || (width == 4 && height == (4 + NTAPS_LUMA - 1))) - { - filterHor<NTAPS_LUMA>(clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_lumaFilter4x4[frac], biMCForDMVR); - } - else - { - filterHor<NTAPS_LUMA>(clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_lumaFilter[frac], biMCForDMVR); - } + filterHor<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_lumaFilter[frac], biMCForDMVR ); + } } - } else { const uint32_t csx = getComponentScaleX( compID, fmt ); CHECK( frac < 0 || csx >= 2 || ( frac << ( 1 - csx ) ) >= CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS, "Invalid fraction" ); - filterHor<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilter[frac << ( 1 - csx )], biMCForDMVR); +#if JVET_P0088_P0353_RPR_FILTERS + if( nFilterIdx == 3 ) + { + filterHor<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilterRPR1[frac << ( 1 - csx )], biMCForDMVR ); + } + else if( nFilterIdx == 4 ) + { + filterHor<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilterRPR2[frac << ( 1 - csx )], biMCForDMVR ); + } + else + { + filterHor<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilter[frac << ( 1 - csx )], biMCForDMVR ); + } +#else + filterHor<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isLast, m_chromaFilter[frac << ( 1 - csx )], biMCForDMVR ); +#endif } } @@ -639,45 +783,68 @@ void InterpolationFilter::filterHor(const ComponentID compID, Pel const *src, in */ void InterpolationFilter::filterVer(const ComponentID compID, Pel const *src, int srcStride, Pel *dst, int dstStride, int width, int height, int frac, bool isFirst, bool isLast, const ChromaFormat fmt, const ClpRng& clpRng, int nFilterIdx, bool biMCForDMVR, bool useAltHpelIf) { +#if JVET_P0088_P0353_RPR_FILTERS + if( frac == 0 && nFilterIdx < 2 ) +#else if( frac == 0 ) +#endif { - m_filterCopy[isFirst][isLast](clpRng, src, srcStride, dst, dstStride, width, height, biMCForDMVR); + m_filterCopy[isFirst][isLast]( clpRng, src, srcStride, dst, dstStride, width, height, biMCForDMVR ); } else if( isLuma( compID ) ) { CHECK( frac < 0 || frac >= LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS, "Invalid fraction" ); - if (nFilterIdx == 1) + if( nFilterIdx == 1 ) { - filterVer<NTAPS_BILINEAR>(clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_bilinearFilterPrec4[frac], biMCForDMVR); + filterVer<NTAPS_BILINEAR>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_bilinearFilterPrec4[frac], biMCForDMVR ); } else if( nFilterIdx == 2 ) { filterVer<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaFilter4x4[frac], biMCForDMVR ); } +#if JVET_P0088_P0353_RPR_FILTERS + else if( nFilterIdx == 3 ) + { + filterVer<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaFilterRPR1[frac], biMCForDMVR ); + } + else if( nFilterIdx == 4 ) + { + filterVer<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaFilterRPR2[frac], biMCForDMVR ); + } +#endif + else if( frac == 8 && useAltHpelIf ) + { + filterVer<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaAltHpelIFilter, biMCForDMVR ); + } + else if( width == 4 && height == 4 ) + { + filterVer<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaFilter4x4[frac], biMCForDMVR ); + } else { - if (frac == 8 && useAltHpelIf) - { - filterVer<NTAPS_LUMA>(clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaAltHpelIFilter, biMCForDMVR); - } - else - { - if (width == 4 && height == 4) - { - filterVer<NTAPS_LUMA>(clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaFilter4x4[frac], biMCForDMVR); - } - else - { - filterVer<NTAPS_LUMA>(clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaFilter[frac], biMCForDMVR); - } + filterVer<NTAPS_LUMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_lumaFilter[frac], biMCForDMVR ); } } - } else { const uint32_t csy = getComponentScaleY( compID, fmt ); CHECK( frac < 0 || csy >= 2 || ( frac << ( 1 - csy ) ) >= CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS, "Invalid fraction" ); - filterVer<NTAPS_CHROMA>(clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_chromaFilter[frac << (1 - csy)], biMCForDMVR); +#if JVET_P0088_P0353_RPR_FILTERS + if( nFilterIdx == 3 ) + { + filterVer<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_chromaFilterRPR1[frac << ( 1 - csy )], biMCForDMVR ); + } + else if( nFilterIdx == 4 ) + { + filterVer<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_chromaFilterRPR2[frac << ( 1 - csy )], biMCForDMVR ); + } + else + { + filterVer<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_chromaFilter[frac << ( 1 - csy )], biMCForDMVR ); + } +#else + filterVer<NTAPS_CHROMA>( clpRng, src, srcStride, dst, dstStride, width, height, isFirst, isLast, m_chromaFilter[frac << ( 1 - csy )], biMCForDMVR ); +#endif } } diff --git a/source/Lib/CommonLib/InterpolationFilter.h b/source/Lib/CommonLib/InterpolationFilter.h index 14f49ec4d994f536459216ec3aa0c974fa35941f..f58d198ed78adcc652d38fe8e0fccacb4aaa4cd9 100644 --- a/source/Lib/CommonLib/InterpolationFilter.h +++ b/source/Lib/CommonLib/InterpolationFilter.h @@ -59,6 +59,12 @@ class InterpolationFilter public: static const TFilterCoeff m_lumaFilter[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_LUMA]; ///< Luma filter taps static const TFilterCoeff m_chromaFilter[CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_CHROMA]; ///< Chroma filter taps +#if JVET_P0088_P0353_RPR_FILTERS + static const TFilterCoeff m_lumaFilterRPR1[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_LUMA]; ///< Luma filter taps 1.5x + static const TFilterCoeff m_lumaFilterRPR2[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_LUMA]; ///< Luma filter taps 2x + static const TFilterCoeff m_chromaFilterRPR1[CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_CHROMA]; ///< Chroma filter taps 1.5x + static const TFilterCoeff m_chromaFilterRPR2[CHROMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_CHROMA]; ///< Chroma filter taps 2x +#endif private: static const TFilterCoeff m_lumaAltHpelIFilter[NTAPS_LUMA]; ///< Luma filter taps static const TFilterCoeff m_bilinearFilter[LUMA_INTERPOLATION_FILTER_SUB_SAMPLE_POSITIONS][NTAPS_BILINEAR]; ///< bilinear filter taps diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index ed99654d7260a2795a252be10eb38a180204de2f..950804f5109275334f8f92e6e9444c69cc958489 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -106,6 +106,8 @@ #define JVET_O0145_ENTRYPOINT_SIGNALLING 0 // JVET-O0145: Not signalling num_entry_point_offsets but derive it at decoder +#define JVET_P0088_P0353_RPR_FILTERS 1 // JVET-P0088 and JVET-P0353 Filters to use for downsampling in RPR + #define JVET_O0625_ALF_PADDING 1 // JVET-O0625/O0654/O0662: Unified padding method in ALF #if !JVET_P0400_REMOVE_SHARED_MERGE_LIST