diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index b3894ed01e7ced2bcda3a0fef84685463d411724..8f51932abdbdfea8cff0f99b3f536819369c4b57 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -259,7 +259,11 @@ static const uint32_t MTS_INTER_MAX_CU_SIZE = 32; ///< static const int NUM_MOST_PROBABLE_MODES = 6; static const int LM_SYMBOL_NUM = (1 + NUM_LMC_MODE); +#if JVET_P0803_COMBINED_MIP_CLEANUP +static const int MAX_NUM_MIP_MODE = 32; ///< maximum number of MIP pred. modes +#else static const int MAX_NUM_MIP_MODE = 35; ///< maximum number of MIP modes +#endif static const int FAST_UDI_MAX_RDMODE_NUM = (NUM_LUMA_MODE + MAX_NUM_MIP_MODE); ///< maximum number of RD comparison in fast-UDI estimation loop static const int MAX_LFNST_COEF_NUM = 16; diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp index 263b138ca48d1ef1b2ba5f6d42baac4caa95bb93..130b6f4429f7f0d42ed2f8ca2fc52af2778a86f4 100644 --- a/source/Lib/CommonLib/IntraPrediction.cpp +++ b/source/Lib/CommonLib/IntraPrediction.cpp @@ -1886,6 +1886,20 @@ void IntraPrediction::xGetLMParameters(const PredictionUnit &pu, const Component } } +#if JVET_P0803_COMBINED_MIP_CLEANUP +void IntraPrediction::initIntraMip( const PredictionUnit &pu, const CompArea &area ) +{ + CHECK( area.width > MIP_MAX_WIDTH || area.height > MIP_MAX_HEIGHT, "Error: block size not supported for MIP" ); + + // prepare input (boundary) data for prediction + CHECK( m_ipaParam.refFilterFlag, "ERROR: unfiltered refs expected for MIP" ); + Pel *ptrSrc = getPredictorPtr( COMPONENT_Y ); + const int srcStride = m_refBufferStride[COMPONENT_Y]; + const int srcHStride = 2; + + m_matrixIntraPred.prepareInputForPred( CPelBuf( ptrSrc, srcStride, srcHStride ), area, pu.cu->slice->getSPS()->getBitDepth( CHANNEL_TYPE_LUMA ) ); +} +#else void IntraPrediction::initIntraMip( const PredictionUnit &pu ) { CHECK( pu.lwidth() > pu.cs->sps->getMaxTbSize() || pu.lheight() > pu.cs->sps->getMaxTbSize(), "Error: block size not supported for MIP" ); @@ -1898,10 +1912,29 @@ void IntraPrediction::initIntraMip( const PredictionUnit &pu ) m_matrixIntraPred.prepareInputForPred(CPelBuf(ptrSrc, srcStride, srcHStride), pu.Y(), pu.cu->slice->getSPS()->getBitDepth(CHANNEL_TYPE_LUMA)); } +#endif void IntraPrediction::predIntraMip( const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu ) { CHECK( compId != COMPONENT_Y, "Error: chroma not supported" ); +#if JVET_P0803_COMBINED_MIP_CLEANUP + CHECK( piPred.width > MIP_MAX_WIDTH || piPred.height > MIP_MAX_HEIGHT, "Error: block size not supported for MIP" ); + CHECK( piPred.width != (1 << floorLog2(piPred.width)) || piPred.height != (1 << floorLog2(piPred.height)), "Error: expecting blocks of size 2^M x 2^N" ); + + // generate mode-specific prediction + const int bitDepth = pu.cu->slice->getSPS()->getBitDepth( CHANNEL_TYPE_LUMA ); + + static_vector<int, MIP_MAX_WIDTH* MIP_MAX_HEIGHT> predMip( piPred.width * piPred.height ); + m_matrixIntraPred.predBlock( predMip.data(), pu.intraDir[CHANNEL_TYPE_LUMA], pu.mipTransposedFlag, bitDepth ); + + for( int y = 0; y < piPred.height; y++ ) + { + for( int x = 0; x < piPred.width; x++ ) + { + piPred.at( x, y ) = Pel(predMip[y * piPred.width + x]); + } + } +#else CHECK( pu.lwidth() > pu.cs->sps->getMaxTbSize() || pu.lheight() > pu.cs->sps->getMaxTbSize(), "Error: block size not supported for MIP" ); CHECK( pu.lwidth() != (1 << floorLog2(pu.lwidth())) || pu.lheight() != (1 << floorLog2(pu.lheight())), "Error: expecting blocks of size 2^M x 2^N" ); @@ -1917,6 +1950,7 @@ void IntraPrediction::predIntraMip( const ComponentID compId, PelBuf &piPred, co piPred.at(x, y) = Pel(predMip[y * pu.lwidth() + x]); } } +#endif } bool IntraPrediction::calCopyRun(CodingStructure &cs, Partitioner& partitioner, uint32_t startPos, uint32_t total, uint32_t &run, ComponentID compBegin) diff --git a/source/Lib/CommonLib/IntraPrediction.h b/source/Lib/CommonLib/IntraPrediction.h index d3c9449ff5304dc1bad10770d999d1123bfbb3be..c4b7d4aed9d6d9eaf6d26306fcfb6e279b8926e9 100644 --- a/source/Lib/CommonLib/IntraPrediction.h +++ b/source/Lib/CommonLib/IntraPrediction.h @@ -167,7 +167,11 @@ public: void initIntraPatternChTypeISP (const CodingUnit& cu, const CompArea& area, PelBuf& piReco, const bool forceRefFilterFlag = false); // use forceRefFilterFlag to get both filtered and unfiltered buffers // Matrix-based intra prediction +#if JVET_P0803_COMBINED_MIP_CLEANUP + void initIntraMip (const PredictionUnit &pu, const CompArea &area); +#else void initIntraMip (const PredictionUnit &pu); +#endif void predIntraMip (const ComponentID compId, PelBuf &piPred, const PredictionUnit &pu); static bool useDPCMForFirstPassIntraEstimation(const PredictionUnit &pu, const uint32_t &uiDirMode); diff --git a/source/Lib/CommonLib/MatrixIntraPrediction.cpp b/source/Lib/CommonLib/MatrixIntraPrediction.cpp index 42c2202affafdae51957e0c48d47d3a91d78b64f..3e33b4caf8d5090d8f15907997d72783b74feb77 100644 --- a/source/Lib/CommonLib/MatrixIntraPrediction.cpp +++ b/source/Lib/CommonLib/MatrixIntraPrediction.cpp @@ -50,8 +50,13 @@ MatrixIntraPrediction::MatrixIntraPrediction(): m_refSamplesTop (MIP_MAX_WIDTH), m_refSamplesLeft(MIP_MAX_HEIGHT), m_blockSize( 0, 0 ), +#if JVET_P0803_COMBINED_MIP_CLEANUP + m_sizeId( 0 ), + m_reducedBdrySize( 0 ), +#else m_numModes( 0 ), m_reducedBoundarySize( 0, 0 ), +#endif m_reducedPredictionSize( 0, 0 ), m_upsmpFactorHor( 0 ), m_upsmpFactorVer( 0 ) @@ -78,6 +83,30 @@ void MatrixIntraPrediction::prepareInputForPred(const CPelBuf &pSrc, const Area& } // Step 3: Compute the reduced boundary via Haar-downsampling (input for the prediction) +#if JVET_P0803_COMBINED_MIP_CLEANUP + const int inputSize = 2 * m_reducedBdrySize; + m_reducedBoundary .resize( inputSize ); + m_reducedBoundaryTransposed.resize( inputSize ); + + int* const topReduced = m_reducedBoundary.data(); + boundaryDownsampling1D( topReduced, m_refSamplesTop.data(), block.width, m_reducedBdrySize ); + + int* const leftReduced = m_reducedBoundary.data() + m_reducedBdrySize; + boundaryDownsampling1D( leftReduced, m_refSamplesLeft.data(), block.height, m_reducedBdrySize ); + + int* const leftReducedTransposed = m_reducedBoundaryTransposed.data(); + int* const topReducedTransposed = m_reducedBoundaryTransposed.data() + m_reducedBdrySize; + for( int x = 0; x < m_reducedBdrySize; x++ ) + { + topReducedTransposed[x] = topReduced[x]; + } + for( int y = 0; y < m_reducedBdrySize; y++ ) + { + leftReducedTransposed[y] = leftReduced[y]; + } + + // Step 4: Rebase the reduced boundary +#else m_reducedBoundary .resize( m_reducedBoundarySize.width + m_reducedBoundarySize.height ); m_reducedBoundaryTransposed.resize( m_reducedBoundarySize.width + m_reducedBoundarySize.height ); @@ -100,11 +129,16 @@ void MatrixIntraPrediction::prepareInputForPred(const CPelBuf &pSrc, const Area& // Step 4: Rebase the reduced boundary const int inputSize = m_reducedBoundarySize.width + m_reducedBoundarySize.height; +#endif m_inputOffset = m_reducedBoundary[0]; m_inputOffsetTransp = m_reducedBoundaryTransposed[0]; +#if JVET_P0803_COMBINED_MIP_CLEANUP + const bool hasFirstCol = (m_sizeId < 2); +#else const bool hasFirstCol = (m_blockSize.width <= 8 && m_blockSize.height <= 8); +#endif m_reducedBoundary [0] = hasFirstCol ? (m_inputOffset - (1 << (bitDepth - 1))) : 0; // first column of matrix not needed for large blocks m_reducedBoundaryTransposed[0] = hasFirstCol ? (m_inputOffsetTransp - (1 << (bitDepth - 1))) : 0; for (int i = 1; i < inputSize; i++) @@ -114,9 +148,14 @@ void MatrixIntraPrediction::prepareInputForPred(const CPelBuf &pSrc, const Area& } } +#if JVET_P0803_COMBINED_MIP_CLEANUP +void MatrixIntraPrediction::predBlock(int* const result, const int modeIdx, const bool transpose, const int bitDepth) +{ +#else void MatrixIntraPrediction::predBlock(int* const result, const int modeIdx, const int bitDepth) { const bool transpose = isTransposed( modeIdx ); +#endif const bool needUpsampling = ( m_upsmpFactorHor > 1 ) || ( m_upsmpFactorVer > 1 ); const uint8_t* matrix; @@ -133,15 +172,27 @@ void MatrixIntraPrediction::predBlock(int* const result, const int modeIdx, cons int* const reducedPred = needUpsampling ? bufReducedPred.data() : result; const int* const reducedBoundary = transpose ? m_reducedBoundaryTransposed.data() : m_reducedBoundary.data(); computeReducedPred( reducedPred, reducedBoundary, matrix, leaveHorOut, leaveVerOut, shiftMatrix, offsetMatrix, +#if JVET_P0803_COMBINED_MIP_CLEANUP + transpose, bitDepth ); +#else transpose, needUpsampling, bitDepth ); +#endif +#if JVET_P0803_COMBINED_MIP_CLEANUP + if( needUpsampling ) + { + predictionUpsampling( result, reducedPred, false ); + } +#else // Reduced prediction is transposed if ( transpose && needUpsampling ). if( needUpsampling ) { predictionUpsampling( result, reducedPred, transpose ); } +#endif } +#if !JVET_P0803_COMBINED_MIP_CLEANUP bool MatrixIntraPrediction::isTransposed(const int modeIdx) const { return ( modeIdx > ( m_numModes / 2 ) ); @@ -158,10 +209,22 @@ int MatrixIntraPrediction::getWeightIdx(const int modeIdx) const return modeIdx; } } +#endif void MatrixIntraPrediction::initPredBlockParams(const Size& block) { m_blockSize = block; +#if JVET_P0803_COMBINED_MIP_CLEANUP + // init size index + m_sizeId = getMipSizeId( m_blockSize ); + + // init reduced boundary size + m_reducedBdrySize = (m_sizeId == 0) ? 2 : 4; + + // init reduced prediction size + if( m_sizeId < 2 ) { m_reducedPredictionSize = Size(4, 4); } + else { m_reducedPredictionSize = Size(std::min<SizeType>(m_blockSize.width, 8), std::min<SizeType>(m_blockSize.height, 8)); } +#else m_numModes = getNumModesMip(m_blockSize); // init reduced boundary size @@ -183,6 +246,7 @@ void MatrixIntraPrediction::initPredBlockParams(const Size& block) { m_reducedPredictionSize = Size(std::min<SizeType>(m_blockSize.width, 8), std::min<SizeType>(m_blockSize.height, 8)); } +#endif // init upsampling factors @@ -195,6 +259,7 @@ void MatrixIntraPrediction::initPredBlockParams(const Size& block) CHECKD((m_upsmpFactorVer < 1) || ((m_upsmpFactorVer & (m_upsmpFactorVer - 1)) != 0), "Need power of two vertical upsampling factor."); } +#if !JVET_P0803_COMBINED_MIP_CLEANUP void MatrixIntraPrediction::doDownsampling(int* dst, const int* src, const SizeType srcLen, const SizeType dstLen) { const SizeType downsmpFactor = srcLen / dstLen; @@ -213,6 +278,7 @@ void MatrixIntraPrediction::doDownsampling(int* dst, const int* src, const SizeT dst[ dstIdx ] = ( sum + roundingOffset ) >> log2DownsmpFactor; } } +#endif void MatrixIntraPrediction::boundaryDownsampling1D(int* reducedDst, const int* const fullSrc, const SizeType srcLen, const SizeType dstLen) @@ -220,7 +286,24 @@ void MatrixIntraPrediction::boundaryDownsampling1D(int* reducedDst, const int* c if (dstLen < srcLen) { // Create reduced boundary by downsampling +#if JVET_P0803_COMBINED_MIP_CLEANUP + const SizeType downsmpFactor = srcLen / dstLen; + const int log2DownsmpFactor = floorLog2(downsmpFactor); + const int roundingOffset = (1 << (log2DownsmpFactor - 1)); + + SizeType srcIdx = 0; + for( SizeType dstIdx = 0; dstIdx < dstLen; dstIdx++ ) + { + int sum = 0; + for( int k = 0; k < downsmpFactor; k++ ) + { + sum += fullSrc[srcIdx++]; + } + reducedDst[dstIdx] = (sum + roundingOffset) >> log2DownsmpFactor; + } +#else doDownsampling(reducedDst, fullSrc, srcLen, dstLen); +#endif } else { @@ -284,9 +367,11 @@ void MatrixIntraPrediction::predictionUpsampling1D(int* const dst, const int* co void MatrixIntraPrediction::predictionUpsampling(int* const dst, const int* const src, const bool transpose) const { +#if !JVET_P0803_COMBINED_MIP_CLEANUP // shorter side is upsampled first if( m_blockSize.height > m_blockSize.width ) { +#endif const int* verSrc = nullptr; SizeType verSrcStep = 0; SizeType verSrcStride = 0; @@ -313,11 +398,16 @@ void MatrixIntraPrediction::predictionUpsampling(int* const dst, const int* cons verSrcStep = transpose ? 1 : m_blockSize.width; verSrcStride = transpose ? m_reducedPredictionSize.height : 1; } +#if JVET_P0803_COMBINED_MIP_CLEANUP + if( m_upsmpFactorVer > 1 ) + { +#endif predictionUpsampling1D( dst, verSrc, m_refSamplesTop.data(), m_reducedPredictionSize.height, m_blockSize.width, verSrcStep, verSrcStride, m_blockSize.width, 1, 1, m_upsmpFactorVer ); } +#if !JVET_P0803_COMBINED_MIP_CLEANUP else { const int* horSrc = nullptr; @@ -352,10 +442,32 @@ void MatrixIntraPrediction::predictionUpsampling(int* const dst, const int* cons horSrcStep, horSrcStride, 1, m_blockSize.width, 1, m_upsmpFactorHor ); } +#endif } void MatrixIntraPrediction::getMatrixData(const uint8_t*& matrix, int &shiftMatrix, int &offsetMatrix, const int modeIdx) const { +#if JVET_P0803_COMBINED_MIP_CLEANUP + switch( m_sizeId ) + { + case 0: matrix = &mipMatrix4x4 [modeIdx][0][0]; + shiftMatrix = mipShiftMatrix4x4 [modeIdx]; + offsetMatrix = mipOffsetMatrix4x4[modeIdx]; + break; + + case 1: matrix = &mipMatrix8x8 [modeIdx][0][0]; + shiftMatrix = mipShiftMatrix8x8 [modeIdx]; + offsetMatrix = mipOffsetMatrix8x8[modeIdx]; + break; + + case 2: matrix = &mipMatrix16x16 [modeIdx][0][0]; + shiftMatrix = mipShiftMatrix16x16 [modeIdx]; + offsetMatrix = mipOffsetMatrix16x16[modeIdx]; + break; + + default: THROW( "Invalid mipSizeId" ); + } +#else const int idx = getWeightIdx( modeIdx ); if( m_blockSize.width == 4 && m_blockSize.height == 4 ) { @@ -375,18 +487,30 @@ void MatrixIntraPrediction::getMatrixData(const uint8_t*& matrix, int &shiftMatr shiftMatrix = mipShiftMatrix16x16 [idx]; offsetMatrix = mipOffsetMatrix16x16[idx]; } +#endif } void MatrixIntraPrediction::computeReducedPred(int*const result, const int* const input, const uint8_t*matrix, const bool leaveHorOut, const bool leaveVerOut, const int shiftMatrix, const int offsetMatrix, +#if JVET_P0803_COMBINED_MIP_CLEANUP + const bool transpose, const int bitDepth ) +#else const bool transpose, const bool needUpsampling, const int bitDepth ) +#endif { +#if JVET_P0803_COMBINED_MIP_CLEANUP + const int inputSize = 2 * m_reducedBdrySize; + + static_vector<int, MIP_MAX_REDUCED_OUTPUT_SAMPLES> resBufTransposed(m_reducedPredictionSize.area()); + int* const resPtr = (transpose) ? resBufTransposed.data() : result; +#else const int inputSize = m_reducedBoundarySize.width + m_reducedBoundarySize.height; // Use local buffer for transposed result if no upsampling will be done. static_vector<int, MIP_MAX_REDUCED_OUTPUT_SAMPLES> resBufTransposed( m_reducedPredictionSize.area() ); int*const resPtr = (transpose && !needUpsampling) ? resBufTransposed.data() : result; +#endif int sum = 0; for (int i = 0; i < inputSize; i++) { sum += input[i]; } @@ -401,7 +525,11 @@ void MatrixIntraPrediction::computeReducedPred(int*const result, const int* cons const int xStep = leaveHorOut ? 2 : 1; const int yStep = leaveVerOut ? intermediateWidth : 0; +#if JVET_P0803_COMBINED_MIP_CLEANUP + const int redSize = (m_sizeId == 2) ? 1 : 0; +#else const int redSize = (m_blockSize.width <= 8 && m_blockSize.height <= 8) ? 0 : 1; +#endif if ( redSize ) weight += xStep-1; int posRes = 0; for (int y = 0; y < intermediateHeight; y++) @@ -427,8 +555,12 @@ void MatrixIntraPrediction::computeReducedPred(int*const result, const int* cons weight += yStep * (inputSize - redSize); } +#if JVET_P0803_COMBINED_MIP_CLEANUP + if( transpose ) +#else // Re-transpose if no upsampling will be done. if( transpose && !needUpsampling ) +#endif { for( int y = 0; y < m_reducedPredictionSize.height; y++ ) { diff --git a/source/Lib/CommonLib/MatrixIntraPrediction.h b/source/Lib/CommonLib/MatrixIntraPrediction.h index fcc1bbd33d9133bc8d5bc71d62ac3a53821fe3a7..e7dd62d6212296f590bad0991b42242d68a2fb55 100644 --- a/source/Lib/CommonLib/MatrixIntraPrediction.h +++ b/source/Lib/CommonLib/MatrixIntraPrediction.h @@ -51,7 +51,11 @@ public: MatrixIntraPrediction(); void prepareInputForPred(const CPelBuf &pSrc, const Area& block, const int bitDepth); +#if JVET_P0803_COMBINED_MIP_CLEANUP + void predBlock(int* const result, const int modeIdx, const bool transpose, const int bitDepth); +#else void predBlock(int* const result, const int modeIdx, const int bitDepth); +#endif private: static_vector<int, MIP_MAX_INPUT_SIZE> m_reducedBoundary; // downsampled boundary of a block @@ -62,8 +66,13 @@ public: static_vector<int, MIP_MAX_HEIGHT> m_refSamplesLeft; // left reference samples for upsampling Size m_blockSize; +#if JVET_P0803_COMBINED_MIP_CLEANUP + int m_sizeId; + int m_reducedBdrySize; +#else int m_numModes; Size m_reducedBoundarySize; +#endif Size m_reducedPredictionSize; unsigned int m_upsmpFactorHor; unsigned int m_upsmpFactorVer; @@ -71,7 +80,9 @@ public: void initPredBlockParams(const Size& block); static void boundaryDownsampling1D(int* reducedDst, const int* const fullSrc, const SizeType srcLen, const SizeType dstLen); +#if !JVET_P0803_COMBINED_MIP_CLEANUP static void doDownsampling( int* dst, const int* src, const SizeType srcLen, const SizeType dstLen ); +#endif void predictionUpsampling( int* const dst, const int* const src, const bool transpose ) const; static void predictionUpsampling1D( int* const dst, const int* const src, const int* const bndry, @@ -83,13 +94,19 @@ public: void getMatrixData(const uint8_t*& matrix, int &shiftMatrix, int &offsetMatrix, const int modeIdx) const; +#if !JVET_P0803_COMBINED_MIP_CLEANUP bool isTransposed( const int modeIdx ) const; int getWeightIdx( const int modeIdx ) const; +#endif void computeReducedPred( int*const result, const int* const input, const uint8_t*matrix, const bool leaveHorOut, const bool leaveVerOut, const int shiftMatrix, const int offsetMatrix, +#if JVET_P0803_COMBINED_MIP_CLEANUP + const bool transpose, const int bitDepth ); +#else const bool transpose, const bool needUpsampling, const int bitDepth ); +#endif }; #endif //__MATRIXINTRAPPREDICTION__ diff --git a/source/Lib/CommonLib/MipData.h b/source/Lib/CommonLib/MipData.h index c179b31a66eb66a0bd0c0ca1875830dc07852648..9bc8e68c7a8baf69898330d0550e87b2e85aac25 100644 --- a/source/Lib/CommonLib/MipData.h +++ b/source/Lib/CommonLib/MipData.h @@ -35,6 +35,865 @@ \brief weight and bias data for matrix-based intra prediction (MIP) */ +#if JVET_P0803_COMBINED_MIP_CLEANUP +ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const uint8_t mipMatrix4x4[16][16][4]) = +{ + { + { 5, 16, 51, 2}, + { 5, 22, 18, 36}, + { 5, 15, 5, 55}, + { 5, 10, 6, 59}, + { 4, 6, 12, 59}, + { 5, 3, 4, 66}, + { 7, 0, 5, 67}, + { 8, 1, 7, 65}, + { 6, 2, 3, 67}, + { 7, 1, 5, 66}, + { 9, 1, 6, 66}, + { 10, 2, 6, 66}, + { 7, 3, 5, 64}, + { 9, 2, 6, 64}, + { 10, 2, 6, 65}, + { 10, 3, 7, 64} + }, + { + { 28, 27, 58, 26}, + { 28, 27, 52, 27}, + { 29, 39, 43, 28}, + { 28, 70, 38, 27}, + { 28, 28, 61, 28}, + { 28, 27, 62, 26}, + { 29, 30, 60, 25}, + { 25, 61, 49, 23}, + { 29, 28, 35, 54}, + { 29, 28, 42, 47}, + { 28, 26, 50, 36}, + { 16, 42, 46, 19}, + { 28, 28, 23, 64}, + { 29, 28, 24, 64}, + { 25, 24, 23, 58}, + { 0, 19, 21, 31} + }, + { + { 28, 27, 39, 26}, + { 29, 32, 29, 27}, + { 29, 60, 31, 27}, + { 27, 68, 31, 26}, + { 28, 27, 51, 27}, + { 28, 39, 39, 26}, + { 26, 64, 33, 28}, + { 21, 64, 27, 35}, + { 27, 28, 38, 50}, + { 19, 44, 31, 51}, + { 10, 57, 22, 54}, + { 7, 53, 16, 58}, + { 19, 31, 12, 72}, + { 6, 47, 14, 64}, + { 0, 50, 15, 60}, + { 2, 48, 15, 60} + }, + { + { 42, 40, 64, 45}, + { 43, 41, 44, 52}, + { 43, 67, 34, 49}, + { 41, 76, 38, 45}, + { 42, 41, 50, 67}, + { 41, 39, 42, 71}, + { 38, 52, 33, 63}, + { 31, 70, 31, 47}, + { 40, 41, 39, 76}, + { 31, 36, 38, 74}, + { 17, 30, 35, 69}, + { 9, 47, 30, 50}, + { 32, 37, 37, 75}, + { 15, 29, 36, 68}, + { 3, 22, 37, 62}, + { 0, 26, 38, 52} + }, + { + { 57, 53, 73, 55}, + { 58, 75, 61, 55}, + { 55, 91, 53, 63}, + { 45, 87, 43, 74}, + { 58, 60, 80, 63}, + { 51, 71, 62, 73}, + { 30, 65, 48, 77}, + { 14, 50, 47, 73}, + { 50, 56, 53, 89}, + { 20, 43, 50, 77}, + { 2, 32, 53, 67}, + { 2, 30, 54, 65}, + { 26, 41, 47, 82}, + { 2, 28, 53, 65}, + { 0, 27, 55, 63}, + { 3, 29, 55, 64} + }, + { + { 23, 19, 88, 8}, + { 23, 44, 61, 25}, + { 22, 64, 24, 52}, + { 21, 56, 0, 71}, + { 21, 25, 53, 61}, + { 20, 26, 31, 80}, + { 20, 22, 21, 88}, + { 19, 20, 17, 88}, + { 20, 22, 19, 89}, + { 19, 21, 19, 89}, + { 18, 20, 20, 88}, + { 17, 19, 20, 86}, + { 19, 20, 20, 87}, + { 18, 21, 21, 86}, + { 16, 21, 21, 85}, + { 13, 19, 21, 83} + }, + { + { 9, 0, 11, 6}, + { 9, 19, 11, 8}, + { 9, 70, 11, 8}, + { 9, 76, 12, 8}, + { 9, 0, 12, 6}, + { 9, 19, 11, 7}, + { 9, 70, 11, 9}, + { 9, 76, 12, 9}, + { 9, 0, 12, 6}, + { 9, 20, 12, 7}, + { 9, 70, 12, 9}, + { 9, 75, 12, 9}, + { 9, 1, 11, 8}, + { 9, 20, 12, 8}, + { 9, 70, 12, 8}, + { 9, 75, 11, 9} + }, + { + { 6, 3, 61, 7}, + { 7, 0, 34, 7}, + { 7, 13, 5, 6}, + { 6, 56, 1, 4}, + { 6, 7, 74, 5}, + { 6, 4, 70, 6}, + { 6, 0, 51, 6}, + { 6, 8, 19, 5}, + { 7, 7, 55, 23}, + { 7, 7, 71, 8}, + { 6, 5, 74, 5}, + { 6, 3, 59, 7}, + { 5, 5, 3, 74}, + { 6, 6, 36, 41}, + { 7, 7, 62, 15}, + { 6, 7, 66, 10} + }, + { + { 35, 26, 78, 28}, + { 34, 39, 35, 33}, + { 34, 96, 32, 35}, + { 35, 102, 35, 35}, + { 31, 30, 107, 25}, + { 29, 34, 66, 24}, + { 31, 93, 32, 31}, + { 35, 101, 34, 35}, + { 31, 31, 64, 72}, + { 19, 28, 86, 30}, + { 18, 85, 47, 20}, + { 31, 99, 34, 33}, + { 32, 32, 27, 106}, + { 12, 26, 52, 71}, + { 0, 72, 60, 19}, + { 20, 93, 37, 26} + }, + { + { 10, 6, 60, 0}, + { 7, 14, 39, 4}, + { 4, 65, 21, 11}, + { 1, 80, 12, 16}, + { 10, 11, 52, 46}, + { 6, 9, 36, 57}, + { 2, 18, 20, 65}, + { 0, 23, 11, 65}, + { 13, 13, 13, 80}, + { 12, 13, 12, 80}, + { 12, 12, 13, 80}, + { 11, 12, 14, 79}, + { 15, 14, 12, 79}, + { 15, 14, 13, 79}, + { 16, 16, 15, 78}, + { 16, 16, 17, 76} + }, + { + { 50, 48, 85, 42}, + { 47, 44, 59, 44}, + { 43, 52, 51, 43}, + { 14, 107, 51, 29}, + { 51, 49, 92, 77}, + { 47, 44, 70, 81}, + { 35, 32, 47, 79}, + { 0, 47, 35, 60}, + { 50, 49, 49, 116}, + { 49, 47, 49, 117}, + { 45, 41, 49, 115}, + { 30, 32, 47, 106}, + { 50, 49, 46, 117}, + { 49, 49, 48, 115}, + { 50, 48, 49, 115}, + { 47, 45, 50, 113} + }, + { + { 67, 65, 96, 61}, + { 66, 65, 90, 62}, + { 68, 83, 79, 64}, + { 59, 102, 70, 61}, + { 67, 67, 93, 74}, + { 68, 67, 93, 74}, + { 64, 75, 88, 69}, + { 30, 85, 69, 49}, + { 67, 67, 68, 97}, + { 68, 67, 68, 98}, + { 43, 60, 69, 80}, + { 4, 68, 65, 40}, + { 66, 66, 63, 101}, + { 62, 63, 62, 99}, + { 22, 49, 60, 76}, + { 0, 65, 64, 41} + }, + { + { 27, 18, 53, 22}, + { 26, 35, 22, 28}, + { 27, 90, 27, 27}, + { 28, 97, 29, 28}, + { 22, 19, 80, 29}, + { 15, 24, 42, 22}, + { 17, 72, 27, 20}, + { 22, 89, 28, 23}, + { 19, 22, 40, 82}, + { 6, 13, 36, 68}, + { 0, 19, 14, 53}, + { 8, 33, 10, 38}, + { 22, 26, 24, 95}, + { 13, 19, 25, 91}, + { 6, 14, 22, 87}, + { 4, 14, 13, 79} + }, + { + { 50, 48, 80, 49}, + { 50, 45, 73, 49}, + { 50, 48, 62, 49}, + { 49, 61, 54, 48}, + { 50, 50, 84, 48}, + { 50, 49, 84, 48}, + { 50, 48, 82, 49}, + { 50, 47, 76, 49}, + { 50, 50, 69, 64}, + { 51, 50, 77, 56}, + { 48, 48, 82, 50}, + { 37, 43, 81, 45}, + { 49, 48, 44, 87}, + { 40, 43, 50, 78}, + { 17, 32, 58, 58}, + { 0, 27, 64, 44} + }, + { + { 29, 26, 37, 36}, + { 24, 42, 16, 40}, + { 25, 62, 35, 28}, + { 28, 54, 51, 22}, + { 24, 29, 22, 52}, + { 9, 44, 21, 31}, + { 16, 50, 54, 14}, + { 27, 40, 65, 19}, + { 17, 36, 21, 49}, + { 0, 40, 41, 10}, + { 15, 37, 65, 9}, + { 28, 34, 66, 21}, + { 16, 41, 36, 33}, + { 6, 37, 54, 3}, + { 19, 32, 64, 12}, + { 28, 33, 62, 24} + }, + { + { 19, 20, 50, 19}, + { 19, 21, 49, 20}, + { 19, 27, 47, 19}, + { 19, 34, 43, 19}, + { 19, 22, 54, 18}, + { 19, 22, 55, 18}, + { 19, 22, 55, 18}, + { 19, 22, 53, 18}, + { 21, 22, 45, 27}, + { 19, 22, 47, 24}, + { 18, 21, 48, 23}, + { 18, 21, 47, 24}, + { 9, 14, 2, 65}, + { 3, 12, 2, 62}, + { 0, 11, 4, 59}, + { 0, 12, 6, 57} + } +}; + +ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const uint8_t mipOffsetMatrix4x4[16]) = +{ 1, 28, 28, 42, 56, 22, 9, 6, 35, 14, 50, 66, 29, 50, 31, 19}; + +ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const uint8_t mipShiftMatrix4x4[16]) = +{ 6, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 5, 6, 5, 5, 5}; + +ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const uint8_t mipMatrix8x8[8][16][8]) = +{ + { + { 18, 77, 44, 26, 0, 17, 18, 19}, + { 19, 70, 83, 26, 16, 13, 16, 17}, + { 20, 40, 98, 36, 16, 16, 15, 16}, + { 20, 29, 75, 68, 15, 17, 16, 16}, + { 19, 82, 61, 29, 14, 10, 12, 22}, + { 21, 59, 88, 30, 17, 13, 14, 17}, + { 23, 46, 93, 36, 16, 17, 14, 16}, + { 23, 33, 96, 43, 16, 18, 15, 17}, + { 19, 82, 64, 30, 16, 17, 8, 17}, + { 22, 61, 89, 29, 17, 17, 12, 15}, + { 24, 44, 94, 38, 17, 17, 15, 16}, + { 25, 34, 90, 47, 16, 19, 15, 17}, + { 19, 77, 61, 30, 15, 17, 20, 10}, + { 22, 63, 83, 30, 17, 16, 18, 10}, + { 24, 44, 89, 39, 17, 18, 16, 16}, + { 24, 35, 82, 50, 16, 19, 16, 17} + }, + { + { 14, 15, 10, 12, 99, 11, 12, 13}, + { 12, 61, 6, 9, 32, 8, 14, 13}, + { 12, 104, 54, 2, 9, 17, 11, 14}, + { 12, 24, 110, 33, 11, 18, 10, 14}, + { 14, 14, 15, 11, 69, 102, 6, 12}, + { 13, 13, 11, 10, 105, 30, 5, 14}, + { 12, 45, 6, 8, 55, 5, 13, 12}, + { 12, 72, 38, 6, 18, 14, 12, 13}, + { 14, 12, 18, 10, 2, 77, 102, 3}, + { 13, 12, 19, 8, 41, 122, 22, 7}, + { 13, 4, 18, 8, 97, 60, 0, 13}, + { 12, 16, 18, 9, 73, 17, 11, 12}, + { 14, 12, 19, 9, 10, 8, 67, 98}, + { 13, 12, 20, 8, 4, 57, 104, 20}, + { 13, 10, 22, 7, 29, 109, 37, 12}, + { 12, 5, 24, 9, 66, 70, 12, 17} + }, + { + { 23, 42, 18, 23, 18, 41, 20, 23}, + { 23, 86, 33, 20, 20, 33, 21, 23}, + { 23, 18, 90, 25, 22, 32, 20, 23}, + { 23, 25, 12, 94, 22, 33, 21, 23}, + { 23, 36, 21, 23, 0, 79, 31, 21}, + { 23, 68, 29, 21, 0, 67, 29, 21}, + { 23, 29, 70, 24, 5, 58, 28, 21}, + { 23, 22, 21, 78, 11, 50, 29, 22}, + { 22, 28, 23, 23, 18, 9, 97, 25}, + { 21, 35, 25, 22, 16, 8, 99, 22}, + { 19, 30, 36, 22, 15, 6, 100, 21}, + { 18, 22, 22, 45, 16, 5, 92, 23}, + { 19, 24, 23, 21, 20, 28, 4, 101}, + { 16, 23, 23, 20, 18, 28, 6, 99}, + { 11, 24, 22, 18, 16, 28, 8, 97}, + { 8, 21, 21, 23, 16, 25, 11, 93} + }, + { + { 45, 61, 48, 48, 60, 81, 44, 44}, + { 45, 46, 72, 53, 41, 84, 46, 43}, + { 45, 42, 60, 78, 38, 76, 50, 43}, + { 44, 46, 43, 94, 39, 63, 55, 45}, + { 44, 44, 53, 51, 43, 83, 68, 44}, + { 45, 33, 59, 63, 39, 68, 77, 44}, + { 44, 43, 42, 79, 38, 54, 85, 46}, + { 41, 46, 40, 82, 39, 44, 80, 52}, + { 44, 41, 49, 52, 43, 39, 98, 60}, + { 41, 40, 46, 63, 43, 33, 92, 66}, + { 34, 43, 39, 70, 41, 30, 80, 75}, + { 26, 40, 41, 68, 35, 36, 62, 83}, + { 39, 42, 45, 52, 41, 43, 35, 117}, + { 26, 44, 41, 56, 38, 44, 30, 115}, + { 8, 36, 44, 53, 28, 51, 23, 108}, + { 0, 26, 48, 51, 22, 56, 21, 103} + }, + { + { 10, 15, 10, 11, 79, 18, 7, 10}, + { 10, 18, 15, 10, 79, 14, 8, 10}, + { 10, 15, 24, 13, 72, 12, 8, 9}, + { 10, 12, 8, 40, 59, 13, 8, 9}, + { 10, 10, 11, 10, 0, 80, 17, 7}, + { 10, 9, 11, 11, 4, 82, 12, 6}, + { 9, 11, 11, 11, 9, 81, 10, 6}, + { 9, 10, 12, 15, 15, 72, 12, 6}, + { 10, 11, 10, 10, 12, 2, 77, 14}, + { 10, 12, 11, 11, 11, 8, 76, 10}, + { 9, 11, 12, 11, 9, 15, 73, 7}, + { 9, 11, 11, 14, 9, 24, 63, 8}, + { 10, 11, 10, 11, 8, 12, 1, 82}, + { 10, 12, 11, 11, 9, 10, 8, 76}, + { 10, 11, 12, 12, 10, 7, 17, 69}, + { 9, 11, 10, 15, 10, 8, 25, 60} + }, + { + { 14, 34, 30, 13, 20, 58, 8, 14}, + { 13, 1, 44, 32, 7, 32, 33, 13}, + { 13, 12, 2, 56, 11, 11, 36, 33}, + { 12, 17, 5, 38, 13, 7, 23, 58}, + { 13, 7, 20, 22, 10, 21, 65, 18}, + { 11, 10, 6, 29, 13, 5, 39, 56}, + { 9, 17, 4, 20, 13, 9, 12, 83}, + { 8, 14, 15, 11, 12, 13, 9, 85}, + { 12, 14, 9, 19, 15, 7, 23, 74}, + { 8, 15, 10, 14, 13, 13, 0, 93}, + { 6, 14, 15, 9, 11, 15, 0, 93}, + { 6, 14, 16, 9, 10, 15, 5, 87}, + { 11, 14, 12, 15, 13, 15, 2, 89}, + { 8, 13, 15, 12, 11, 15, 3, 88}, + { 6, 14, 15, 11, 11, 16, 4, 87}, + { 6, 14, 15, 12, 11, 16, 6, 83} + }, + { + { 10, 6, 9, 11, 70, 11, 8, 9}, + { 9, 8, 6, 11, 49, 4, 10, 8}, + { 9, 38, 4, 11, 25, 6, 11, 8}, + { 9, 41, 22, 14, 15, 9, 11, 8}, + { 9, 8, 9, 11, 21, 68, 11, 7}, + { 9, 6, 7, 11, 49, 49, 4, 8}, + { 8, 9, 4, 11, 64, 23, 6, 8}, + { 9, 16, 7, 9, 52, 11, 11, 7}, + { 9, 10, 8, 10, 7, 19, 73, 5}, + { 8, 9, 7, 11, 4, 50, 51, 0}, + { 8, 9, 7, 11, 15, 66, 24, 3}, + { 9, 10, 6, 12, 33, 53, 14, 6}, + { 8, 9, 8, 10, 11, 5, 21, 67}, + { 7, 10, 6, 11, 11, 1, 55, 37}, + { 7, 11, 6, 11, 8, 13, 69, 15}, + { 8, 12, 6, 12, 11, 31, 52, 9} + }, + { + { 26, 43, 21, 27, 21, 46, 23, 26}, + { 26, 66, 67, 19, 25, 27, 28, 26}, + { 27, 18, 64, 63, 27, 27, 27, 27}, + { 28, 28, 16, 101, 28, 27, 27, 28}, + { 25, 42, 27, 24, 0, 81, 39, 21}, + { 25, 39, 84, 23, 23, 32, 28, 25}, + { 27, 22, 40, 84, 28, 25, 27, 27}, + { 29, 28, 15, 102, 28, 28, 27, 28}, + { 24, 34, 37, 22, 21, 19, 87, 30}, + { 25, 22, 82, 38, 25, 29, 33, 25}, + { 28, 26, 27, 95, 27, 28, 25, 27}, + { 30, 27, 17, 101, 28, 28, 27, 28}, + { 24, 24, 42, 27, 27, 27, 12, 95}, + { 26, 19, 64, 55, 29, 28, 23, 39}, + { 29, 28, 26, 94, 27, 28, 27, 26}, + { 30, 28, 20, 98, 28, 28, 27, 30} + } +}; + +ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const short mipOffsetMatrix8x8[8]) = +{ 15, 14, 23, 45, 10, 14, 10, 27}; + +ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const short mipShiftMatrix8x8[8]) = +{ 7, 7, 6, 6, 6, 6, 6, 6}; + +ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const uint8_t mipMatrix16x16[6][64][7]) = +{ + { + { 22, 13, 15, 50, 16, 17, 14}, + { 55, 5, 15, 25, 22, 16, 14}, + { 83, 7, 14, 18, 22, 17, 14}, + { 58, 47, 7, 15, 21, 17, 15}, + { 15, 81, 9, 12, 20, 18, 14}, + { 5, 61, 38, 12, 19, 18, 14}, + { 14, 20, 73, 13, 17, 18, 15}, + { 18, 4, 84, 16, 16, 19, 16}, + { 30, 12, 15, 57, 36, 15, 14}, + { 54, 8, 14, 44, 33, 18, 13}, + { 69, 14, 12, 29, 32, 20, 12}, + { 48, 46, 8, 18, 30, 22, 13}, + { 17, 68, 14, 11, 26, 24, 13}, + { 10, 47, 43, 10, 22, 24, 13}, + { 16, 16, 70, 12, 18, 24, 14}, + { 20, 6, 77, 15, 16, 24, 16}, + { 24, 15, 15, 28, 67, 15, 15}, + { 38, 14, 14, 34, 52, 23, 13}, + { 46, 21, 13, 29, 45, 27, 11}, + { 36, 38, 13, 19, 38, 31, 11}, + { 21, 46, 22, 13, 31, 34, 11}, + { 18, 32, 43, 10, 26, 34, 12}, + { 21, 13, 62, 11, 21, 33, 14}, + { 22, 7, 66, 13, 18, 31, 17}, + { 18, 17, 15, 12, 58, 40, 12}, + { 22, 19, 15, 18, 50, 42, 12}, + { 24, 23, 15, 19, 44, 45, 11}, + { 25, 27, 19, 16, 37, 47, 11}, + { 24, 26, 27, 13, 31, 48, 12}, + { 25, 18, 39, 11, 27, 46, 13}, + { 25, 12, 48, 10, 23, 43, 16}, + { 25, 11, 51, 11, 20, 40, 19}, + { 16, 17, 16, 14, 24, 71, 13}, + { 14, 19, 16, 15, 27, 67, 14}, + { 14, 20, 17, 15, 26, 66, 13}, + { 18, 18, 21, 15, 24, 65, 13}, + { 24, 14, 27, 15, 22, 64, 14}, + { 27, 12, 31, 13, 20, 61, 16}, + { 27, 13, 35, 12, 19, 56, 19}, + { 26, 14, 37, 12, 18, 50, 23}, + { 15, 16, 16, 17, 8, 68, 31}, + { 13, 17, 17, 16, 8, 72, 26}, + { 13, 17, 18, 17, 8, 74, 23}, + { 16, 14, 21, 17, 8, 73, 22}, + { 21, 11, 24, 17, 9, 72, 22}, + { 25, 11, 24, 16, 9, 69, 24}, + { 26, 14, 25, 15, 10, 64, 26}, + { 25, 15, 28, 14, 12, 56, 30}, + { 14, 15, 16, 16, 9, 37, 62}, + { 14, 15, 17, 18, 4, 52, 51}, + { 15, 14, 18, 19, 1, 60, 44}, + { 17, 13, 19, 20, 0, 64, 41}, + { 20, 11, 20, 19, 1, 63, 40}, + { 22, 12, 20, 18, 3, 61, 40}, + { 23, 14, 20, 17, 5, 58, 40}, + { 23, 15, 22, 16, 8, 52, 42}, + { 16, 14, 17, 16, 12, 15, 81}, + { 17, 13, 17, 17, 6, 29, 71}, + { 18, 13, 18, 19, 3, 38, 64}, + { 18, 13, 18, 19, 1, 44, 60}, + { 19, 13, 17, 20, 2, 45, 58}, + { 20, 14, 17, 19, 3, 45, 56}, + { 21, 14, 18, 18, 5, 45, 55}, + { 22, 15, 19, 18, 7, 43, 53} + }, + { + { 42, 21, 26, 96, 39, 29, 20}, + { 42, 32, 28, 49, 66, 35, 21}, + { 30, 41, 30, 29, 73, 40, 23}, + { 23, 42, 35, 23, 72, 42, 26}, + { 25, 34, 44, 22, 68, 46, 26}, + { 26, 32, 49, 22, 65, 47, 25}, + { 24, 33, 53, 21, 62, 47, 25}, + { 22, 30, 62, 21, 57, 47, 25}, + { 27, 25, 27, 46, 97, 33, 22}, + { 11, 31, 31, 22, 94, 53, 22}, + { 0, 29, 35, 16, 89, 60, 26}, + { 6, 17, 41, 15, 86, 62, 28}, + { 20, 4, 42, 16, 84, 63, 28}, + { 26, 8, 35, 17, 84, 61, 28}, + { 23, 24, 25, 18, 83, 60, 27}, + { 21, 31, 27, 19, 77, 58, 28}, + { 16, 22, 27, 14, 107, 48, 24}, + { 11, 21, 32, 13, 84, 70, 26}, + { 11, 17, 36, 14, 77, 73, 29}, + { 13, 15, 35, 15, 77, 71, 31}, + { 16, 14, 34, 15, 80, 68, 30}, + { 17, 16, 31, 15, 84, 64, 30}, + { 19, 19, 29, 16, 85, 61, 29}, + { 19, 23, 30, 18, 81, 60, 29}, + { 17, 18, 28, 14, 81, 76, 24}, + { 15, 17, 31, 15, 71, 77, 33}, + { 15, 16, 33, 14, 70, 74, 36}, + { 15, 17, 32, 14, 73, 71, 36}, + { 15, 18, 32, 13, 77, 67, 36}, + { 15, 18, 32, 13, 81, 65, 34}, + { 16, 17, 32, 13, 82, 64, 32}, + { 18, 19, 32, 15, 78, 63, 32}, + { 18, 17, 28, 18, 52, 97, 31}, + { 16, 16, 31, 15, 64, 76, 41}, + { 14, 17, 31, 14, 66, 72, 43}, + { 15, 17, 32, 13, 70, 70, 42}, + { 16, 18, 33, 11, 72, 70, 38}, + { 16, 18, 33, 11, 74, 71, 35}, + { 17, 17, 34, 13, 73, 72, 32}, + { 18, 19, 33, 14, 70, 72, 32}, + { 17, 19, 26, 16, 39, 87, 55}, + { 14, 19, 29, 13, 57, 78, 49}, + { 15, 18, 31, 12, 61, 76, 45}, + { 15, 18, 32, 13, 63, 76, 42}, + { 16, 17, 33, 13, 63, 79, 38}, + { 17, 15, 35, 13, 62, 82, 34}, + { 18, 15, 36, 13, 62, 82, 33}, + { 19, 18, 34, 15, 59, 81, 33}, + { 17, 19, 25, 15, 34, 59, 89}, + { 14, 19, 29, 13, 47, 80, 56}, + { 14, 19, 31, 12, 54, 84, 44}, + { 16, 18, 32, 13, 57, 83, 41}, + { 17, 17, 33, 14, 55, 85, 38}, + { 18, 15, 35, 14, 53, 87, 36}, + { 19, 14, 36, 15, 53, 86, 35}, + { 20, 17, 36, 17, 52, 81, 37}, + { 19, 19, 26, 17, 32, 42, 105}, + { 17, 19, 28, 15, 40, 75, 65}, + { 16, 19, 30, 14, 45, 84, 49}, + { 17, 18, 32, 14, 50, 83, 45}, + { 18, 17, 33, 16, 50, 82, 43}, + { 19, 16, 35, 16, 49, 84, 40}, + { 20, 15, 38, 17, 48, 83, 40}, + { 21, 17, 38, 18, 48, 78, 41} + }, + { + { 52, 46, 46, 55, 50, 46, 47}, + { 65, 45, 45, 42, 52, 47, 47}, + { 74, 48, 45, 40, 51, 48, 47}, + { 67, 61, 44, 39, 50, 48, 48}, + { 52, 74, 45, 39, 48, 48, 49}, + { 44, 75, 53, 39, 47, 48, 50}, + { 44, 57, 71, 40, 46, 46, 51}, + { 50, 31, 92, 42, 45, 41, 55}, + { 55, 45, 45, 48, 61, 48, 46}, + { 65, 46, 45, 36, 57, 53, 46}, + { 72, 50, 44, 31, 54, 54, 48}, + { 66, 61, 44, 31, 51, 54, 49}, + { 54, 73, 45, 32, 48, 52, 52}, + { 45, 76, 52, 33, 46, 49, 55}, + { 45, 59, 70, 36, 44, 44, 59}, + { 50, 30, 93, 40, 43, 37, 64}, + { 54, 46, 45, 39, 66, 53, 46}, + { 65, 46, 45, 31, 57, 60, 47}, + { 71, 50, 44, 26, 52, 61, 50}, + { 67, 60, 44, 26, 48, 58, 53}, + { 56, 72, 45, 27, 45, 53, 58}, + { 47, 76, 51, 29, 43, 47, 63}, + { 46, 59, 69, 33, 41, 39, 69}, + { 51, 29, 93, 37, 40, 30, 76}, + { 53, 46, 46, 35, 60, 64, 47}, + { 64, 47, 45, 27, 53, 65, 50}, + { 71, 50, 45, 22, 49, 62, 55}, + { 68, 59, 44, 22, 46, 57, 61}, + { 58, 71, 45, 24, 43, 50, 67}, + { 48, 76, 51, 27, 41, 41, 74}, + { 46, 59, 69, 32, 39, 31, 82}, + { 51, 30, 93, 36, 38, 21, 88}, + { 52, 46, 46, 35, 51, 71, 50}, + { 63, 47, 45, 24, 51, 63, 58}, + { 70, 51, 45, 19, 49, 56, 65}, + { 68, 59, 44, 19, 45, 50, 72}, + { 58, 71, 45, 22, 42, 41, 80}, + { 48, 76, 51, 26, 39, 31, 88}, + { 46, 59, 69, 30, 37, 21, 95}, + { 51, 30, 93, 34, 36, 13, 100}, + { 52, 46, 46, 35, 47, 65, 61}, + { 62, 47, 45, 24, 49, 56, 69}, + { 69, 51, 45, 19, 47, 47, 77}, + { 68, 60, 44, 19, 44, 38, 85}, + { 59, 71, 45, 22, 40, 29, 94}, + { 49, 75, 51, 25, 37, 19, 102}, + { 47, 59, 69, 28, 35, 11, 108}, + { 52, 31, 93, 33, 34, 6, 110}, + { 52, 47, 46, 36, 46, 50, 77}, + { 61, 48, 45, 26, 46, 42, 84}, + { 67, 52, 45, 21, 44, 34, 92}, + { 66, 60, 44, 21, 41, 26, 100}, + { 59, 70, 46, 22, 38, 17, 108}, + { 50, 73, 53, 25, 35, 10, 114}, + { 48, 57, 70, 28, 33, 3, 118}, + { 52, 31, 92, 32, 32, 1, 118}, + { 52, 47, 46, 38, 45, 32, 93}, + { 59, 49, 46, 30, 43, 27, 99}, + { 65, 53, 46, 25, 41, 21, 106}, + { 64, 60, 46, 23, 38, 15, 111}, + { 58, 67, 48, 24, 36, 9, 117}, + { 51, 68, 56, 25, 34, 4, 121}, + { 49, 55, 72, 27, 32, 0, 123}, + { 52, 32, 92, 31, 30, 0, 123} + }, + { + { 18, 16, 16, 71, 13, 16, 16}, + { 36, 14, 16, 63, 18, 15, 17}, + { 64, 11, 16, 60, 20, 13, 17}, + { 64, 30, 13, 55, 22, 13, 17}, + { 33, 63, 9, 50, 25, 12, 18}, + { 15, 64, 24, 44, 27, 11, 18}, + { 19, 27, 59, 38, 30, 10, 18}, + { 24, 0, 81, 32, 31, 12, 18}, + { 22, 16, 16, 65, 46, 10, 17}, + { 25, 17, 16, 63, 50, 8, 18}, + { 35, 16, 16, 58, 54, 6, 19}, + { 41, 19, 16, 53, 58, 6, 19}, + { 36, 30, 15, 48, 62, 5, 19}, + { 28, 35, 20, 43, 63, 6, 19}, + { 26, 24, 35, 37, 62, 8, 18}, + { 26, 10, 50, 31, 59, 11, 19}, + { 18, 17, 16, 22, 81, 10, 18}, + { 18, 18, 16, 22, 81, 12, 19}, + { 19, 18, 16, 21, 81, 13, 19}, + { 22, 16, 17, 20, 80, 15, 18}, + { 25, 16, 17, 20, 77, 20, 17}, + { 26, 19, 17, 20, 73, 25, 16}, + { 25, 19, 20, 20, 68, 29, 16}, + { 24, 16, 27, 21, 60, 31, 17}, + { 16, 17, 16, 9, 59, 45, 14}, + { 16, 17, 16, 10, 55, 49, 14}, + { 16, 17, 16, 12, 50, 54, 14}, + { 17, 16, 16, 13, 45, 59, 13}, + { 19, 15, 16, 15, 39, 63, 13}, + { 21, 16, 16, 17, 35, 66, 14}, + { 22, 17, 16, 18, 33, 65, 16}, + { 22, 17, 19, 18, 33, 59, 21}, + { 17, 16, 16, 15, 20, 78, 16}, + { 17, 16, 16, 16, 18, 77, 19}, + { 17, 16, 15, 17, 15, 77, 22}, + { 17, 16, 15, 17, 13, 76, 24}, + { 18, 16, 15, 18, 11, 75, 27}, + { 18, 16, 15, 19, 11, 71, 31}, + { 19, 17, 15, 19, 13, 65, 35}, + { 19, 17, 16, 18, 16, 57, 39}, + { 17, 16, 16, 18, 9, 61, 42}, + { 17, 16, 15, 18, 10, 55, 47}, + { 18, 16, 15, 18, 9, 51, 52}, + { 18, 17, 15, 18, 9, 47, 56}, + { 18, 17, 15, 18, 10, 43, 60}, + { 18, 17, 14, 18, 11, 39, 63}, + { 18, 18, 14, 17, 12, 36, 65}, + { 19, 17, 15, 18, 13, 35, 65}, + { 16, 16, 15, 16, 14, 24, 75}, + { 17, 17, 15, 17, 14, 21, 78}, + { 17, 17, 15, 17, 14, 19, 80}, + { 18, 17, 15, 17, 13, 17, 82}, + { 18, 18, 14, 17, 13, 16, 84}, + { 18, 18, 15, 17, 13, 15, 84}, + { 19, 17, 15, 17, 13, 16, 84}, + { 19, 17, 16, 17, 14, 18, 81}, + { 16, 16, 16, 16, 16, 8, 89}, + { 17, 16, 16, 16, 16, 8, 89}, + { 18, 17, 15, 16, 15, 8, 90}, + { 18, 18, 15, 16, 15, 8, 90}, + { 19, 18, 15, 17, 15, 8, 90}, + { 19, 18, 15, 17, 15, 7, 90}, + { 19, 17, 16, 17, 14, 8, 90}, + { 19, 17, 17, 17, 15, 10, 87} + }, + { + { 29, 12, 13, 53, 18, 11, 15}, + { 56, 12, 13, 24, 32, 7, 16}, + { 54, 32, 12, 12, 33, 11, 15}, + { 21, 61, 15, 8, 27, 18, 13}, + { 5, 54, 36, 8, 20, 22, 13}, + { 10, 21, 64, 9, 15, 24, 16}, + { 16, 2, 75, 11, 11, 23, 23}, + { 16, 2, 68, 12, 9, 19, 33}, + { 29, 16, 14, 41, 56, 2, 17}, + { 28, 29, 15, 18, 56, 10, 15}, + { 14, 42, 21, 7, 42, 24, 13}, + { 6, 36, 37, 7, 25, 35, 14}, + { 11, 14, 55, 10, 13, 37, 21}, + { 16, 0, 61, 11, 8, 33, 31}, + { 16, 0, 56, 11, 6, 26, 43}, + { 15, 6, 46, 12, 7, 20, 53}, + { 13, 22, 16, 9, 73, 17, 14}, + { 8, 28, 22, 9, 46, 40, 11}, + { 6, 23, 32, 11, 21, 53, 15}, + { 11, 9, 43, 13, 9, 50, 27}, + { 16, 0, 46, 14, 4, 40, 42}, + { 17, 2, 41, 14, 5, 28, 55}, + { 15, 7, 34, 13, 6, 20, 65}, + { 14, 11, 29, 12, 9, 15, 69}, + { 10, 18, 19, 8, 35, 62, 9}, + { 9, 16, 25, 15, 13, 67, 18}, + { 12, 9, 32, 17, 4, 54, 36}, + { 15, 5, 34, 17, 4, 36, 53}, + { 16, 4, 31, 15, 7, 22, 67}, + { 16, 8, 27, 15, 9, 14, 75}, + { 14, 12, 22, 13, 10, 11, 79}, + { 12, 14, 21, 12, 12, 10, 78}, + { 12, 13, 19, 16, 6, 73, 23}, + { 13, 10, 24, 17, 4, 49, 46}, + { 14, 7, 26, 17, 7, 27, 65}, + { 15, 7, 25, 16, 10, 13, 77}, + { 15, 9, 22, 15, 12, 7, 83}, + { 14, 12, 19, 14, 13, 5, 85}, + { 13, 14, 18, 13, 13, 5, 85}, + { 12, 14, 18, 12, 14, 7, 82}, + { 14, 12, 19, 16, 7, 40, 56}, + { 14, 9, 22, 15, 11, 17, 74}, + { 14, 8, 22, 15, 13, 6, 84}, + { 14, 9, 21, 15, 14, 2, 87}, + { 13, 11, 18, 14, 14, 2, 88}, + { 13, 13, 17, 14, 15, 2, 88}, + { 12, 14, 16, 13, 16, 3, 87}, + { 12, 15, 16, 12, 15, 6, 83}, + { 14, 11, 18, 14, 14, 10, 81}, + { 14, 9, 19, 14, 15, 3, 87}, + { 14, 10, 19, 14, 15, 0, 90}, + { 13, 11, 17, 14, 15, 0, 90}, + { 13, 12, 17, 14, 15, 1, 89}, + { 13, 14, 16, 13, 16, 2, 88}, + { 12, 15, 15, 12, 16, 3, 86}, + { 12, 14, 16, 13, 16, 6, 83}, + { 13, 11, 17, 14, 16, 2, 87}, + { 14, 11, 18, 14, 16, 1, 88}, + { 14, 11, 17, 14, 15, 2, 88}, + { 13, 13, 17, 14, 15, 3, 87}, + { 13, 13, 17, 14, 15, 3, 86}, + { 13, 14, 16, 13, 16, 4, 85}, + { 12, 15, 16, 12, 16, 5, 83}, + { 12, 15, 16, 13, 15, 7, 81} + }, + { + { 11, 11, 11, 53, 9, 12, 11}, + { 18, 10, 10, 32, 13, 10, 11}, + { 40, 8, 11, 20, 13, 11, 11}, + { 56, 14, 9, 16, 13, 12, 10}, + { 47, 37, 6, 13, 12, 12, 10}, + { 23, 60, 10, 12, 13, 11, 11}, + { 10, 50, 33, 11, 12, 11, 11}, + { 13, 15, 66, 12, 12, 11, 11}, + { 15, 11, 11, 62, 26, 9, 10}, + { 13, 12, 10, 57, 17, 11, 10}, + { 17, 12, 10, 43, 15, 11, 10}, + { 34, 8, 11, 30, 14, 12, 10}, + { 49, 12, 10, 22, 13, 12, 10}, + { 45, 31, 7, 17, 13, 12, 10}, + { 28, 49, 11, 14, 13, 12, 10}, + { 17, 41, 31, 13, 13, 11, 10}, + { 14, 11, 11, 33, 59, 6, 11}, + { 13, 11, 11, 48, 42, 8, 10}, + { 12, 12, 11, 51, 30, 9, 10}, + { 18, 10, 11, 45, 22, 11, 10}, + { 31, 8, 11, 37, 17, 12, 10}, + { 41, 13, 10, 28, 15, 12, 9}, + { 39, 27, 8, 21, 15, 12, 10}, + { 29, 36, 15, 17, 15, 12, 10}, + { 11, 12, 11, 11, 63, 26, 8}, + { 12, 11, 11, 23, 61, 16, 10}, + { 12, 12, 11, 34, 53, 10, 10}, + { 13, 12, 11, 41, 43, 9, 10}, + { 18, 10, 11, 42, 33, 9, 10}, + { 27, 9, 11, 37, 26, 10, 10}, + { 33, 14, 10, 31, 22, 11, 10}, + { 32, 23, 12, 24, 20, 11, 10}, + { 11, 12, 11, 10, 32, 61, 5}, + { 11, 12, 11, 11, 49, 42, 6}, + { 11, 12, 11, 17, 58, 26, 8}, + { 11, 12, 11, 25, 58, 16, 9}, + { 13, 11, 11, 32, 52, 11, 9}, + { 17, 10, 11, 35, 43, 10, 10}, + { 23, 11, 10, 34, 35, 10, 10}, + { 27, 15, 11, 29, 29, 12, 9}, + { 11, 12, 11, 13, 9, 70, 17}, + { 11, 11, 11, 12, 23, 65, 10}, + { 11, 12, 10, 12, 38, 53, 6}, + { 11, 12, 10, 14, 51, 37, 7}, + { 11, 11, 11, 20, 56, 24, 8}, + { 12, 11, 11, 26, 53, 17, 9}, + { 16, 11, 11, 30, 47, 14, 9}, + { 20, 13, 11, 30, 38, 14, 10}, + { 11, 11, 10, 13, 9, 35, 52}, + { 11, 11, 10, 13, 11, 51, 34}, + { 11, 11, 10, 13, 20, 57, 20}, + { 11, 12, 10, 13, 33, 52, 12}, + { 10, 12, 10, 14, 44, 42, 10}, + { 11, 12, 10, 18, 49, 32, 9}, + { 12, 12, 11, 23, 49, 24, 10}, + { 15, 13, 11, 25, 43, 21, 10}, + { 11, 11, 11, 11, 16, 0, 81}, + { 10, 12, 10, 12, 16, 16, 65}, + { 11, 11, 10, 13, 17, 33, 47}, + { 11, 12, 10, 13, 22, 43, 31}, + { 11, 12, 10, 13, 29, 45, 21}, + { 11, 12, 11, 15, 37, 40, 16}, + { 11, 12, 11, 18, 41, 34, 14}, + { 12, 13, 12, 20, 40, 28, 14} + } +}; + +ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const uint8_t mipOffsetMatrix16x16[6]) = +{ 15, 19, 46, 16, 14, 11}; + +ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const uint8_t mipShiftMatrix16x16[6]) = +{ 6, 7, 5, 6, 6, 6}; +#else ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const uint8_t mipMatrix4x4[18][16][4]) = { { @@ -964,3 +1823,4 @@ ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const uint8_t mipOffsetMatrix16x16[6]) = ALIGN_DATA(MEMORY_ALIGN_DEF_SIZE, const uint8_t mipShiftMatrix16x16[6]) = { 7, 5, 6, 6, 6, 6 }; +#endif \ No newline at end of file diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 28207f27b0a3b7282aba2a1cb17f49a87ae2d7e2..f47bc9d5ac1ed81b56f4ab2635b8522e40ef6056 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,9 @@ #include <assert.h> #include <cassert> + +#define JVET_P0803_COMBINED_MIP_CLEANUP 1 // JVET-P0803: Several MIP cleanups + #define JVET_P0641_REMOVE_2xN_CHROMA_INTRA 1 // JVET-P0641: removing 2xN chroma intra blocks #define JVET_P0206_TMVP_flags 1 // JVET-P0206: Signalling TMVP usage (remove pps TMVP idc and constraint when RPR is used) diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp index af23619b5ea15f8fa304513b9faf7fca99d29e05..12a75b1a4467a5bb7304f131c2ab48c281fbeffb 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -514,6 +514,9 @@ void PredictionUnit::initData() // intra data - need this default initialization for PCM intraDir[0] = DC_IDX; intraDir[1] = PLANAR_IDX; +#if JVET_P0803_COMBINED_MIP_CLEANUP + mipTransposedFlag = false; +#endif multiRefIdx = 0; // inter data @@ -565,6 +568,9 @@ PredictionUnit& PredictionUnit::operator=(const IntraPredictionData& predData) { intraDir[i] = predData.intraDir[i]; } +#if JVET_P0803_COMBINED_MIP_CLEANUP + mipTransposedFlag = predData.mipTransposedFlag; +#endif multiRefIdx = predData.multiRefIdx; return *this; @@ -619,6 +625,9 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other ) { intraDir[ i ] = other.intraDir[ i ]; } +#if JVET_P0803_COMBINED_MIP_CLEANUP + mipTransposedFlag = other.mipTransposedFlag; +#endif multiRefIdx = other.multiRefIdx; mergeFlag = other.mergeFlag; diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h index 1cfc5a798da2558b05a0e82cebc72ba4eff53507..c81df32a28253440eed4441153dbc7ebe219e16b 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -377,6 +377,9 @@ struct CodingUnit : public UnitArea struct IntraPredictionData { uint32_t intraDir[MAX_NUM_CHANNEL_TYPE]; +#if JVET_P0803_COMBINED_MIP_CLEANUP + bool mipTransposedFlag; +#endif int multiRefIdx; }; diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index 95141fe5bfba2f4255b414d800c0391218af6fe4..e5b1bcd3e835a445372ecf7a1f5b2eeac173944e 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -3917,6 +3917,15 @@ uint32_t getCtuAddr( const Position& pos, const PreCalcValues& pcv ) int getNumModesMip(const Size& block) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + switch( getMipSizeId(block) ) + { + case 0: return 16; + case 1: return 8; + case 2: return 6; + default: THROW( "Invalid mipSizeId" ); + } +#else if (block.width > (4 * block.height) || block.height > (4 * block.width)) { return 0; @@ -3934,13 +3943,34 @@ int getNumModesMip(const Size& block) { return 11; } +#endif } +#if JVET_P0803_COMBINED_MIP_CLEANUP +int getMipSizeId(const Size& block) +{ + if( block.width == 4 && block.height == 4 ) + { + return 0; + } + else if( block.width <= 8 && block.height <= 8 ) + { + return 1; + } + else + { + return 2; + } + +} +#endif +#if !JVET_P0803_COMBINED_MIP_CLEANUP bool mipModesAvailable(const Size& block) { return (getNumModesMip(block)); } +#endif bool allowLfnstWithMip(const Size& block) { diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h index 497679860c42c1483a8f7307c98f2ac1d29d9d3c..820c3f5356ece172684489d75fd7b63c86c19e14 100644 --- a/source/Lib/CommonLib/UnitTools.h +++ b/source/Lib/CommonLib/UnitTools.h @@ -217,7 +217,12 @@ namespace TU uint32_t getCtuAddr (const Position& pos, const PreCalcValues &pcv); int getNumModesMip (const Size& block); +#if JVET_P0803_COMBINED_MIP_CLEANUP +int getMipSizeId (const Size& block); +#endif +#if !JVET_P0803_COMBINED_MIP_CLEANUP bool mipModesAvailable(const Size& block); +#endif bool allowLfnstWithMip(const Size& block); template<typename T, size_t N> diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 8b3a7fad91cfaf0c404db8d3b385947c1912aea9..7fc535971f61de81ed390caca58d4f4937eb8b0a 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -3918,6 +3918,9 @@ void CABACReader::mip_flag( CodingUnit& cu ) cu.mipFlag = false; return; } +#if JVET_P0803_COMBINED_MIP_CLEANUP + CHECK( cu.lwidth() > MIP_MAX_WIDTH || cu.lheight() > MIP_MAX_HEIGHT, "Error: block size not supported for MIP" ); +#else if( cu.lwidth() > cu.cs->sps->getMaxTbSize() || cu.lheight() > cu.cs->sps->getMaxTbSize()) { cu.mipFlag = false; @@ -3928,6 +3931,7 @@ void CABACReader::mip_flag( CodingUnit& cu ) cu.mipFlag = false; return; } +#endif unsigned ctxId = DeriveCtx::CtxMipFlag( cu ); cu.mipFlag = m_BinDecoder.decodeBin( Ctx::MipFlag( ctxId ) ); @@ -3950,6 +3954,19 @@ void CABACReader::mip_pred_modes( CodingUnit &cu ) void CABACReader::mip_pred_mode( PredictionUnit &pu ) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + CHECK( pu.lwidth() > MIP_MAX_WIDTH || pu.lheight() > MIP_MAX_HEIGHT, "Error: block size not supported" ); + + pu.mipTransposedFlag = bool(m_BinDecoder.decodeBinEP()); + + uint32_t mipMode; + const int numModes = getNumModesMip( pu.Y() ); + xReadTruncBinCode( mipMode, numModes ); + pu.intraDir[CHANNEL_TYPE_LUMA] = mipMode; + CHECKD( pu.intraDir[CHANNEL_TYPE_LUMA] < 0 || pu.intraDir[CHANNEL_TYPE_LUMA] >= numModes, "Invalid MIP mode" ); + + DTRACE( g_trace_ctx, D_SYNTAX, "mip_pred_mode() pos=(%d,%d) mode=%d transposed=%d\n", pu.lumaPos().x, pu.lumaPos().y, pu.intraDir[CHANNEL_TYPE_LUMA], pu.mipTransposedFlag ? 1 : 0 ); +#else CHECK( pu.lwidth() > pu.cs->sps->getMaxTbSize() || pu.lheight() > pu.cs->sps->getMaxTbSize(), "Error: block size not supported" ); const int numModes = getNumModesMip( pu.Y() ); CHECKD( numModes > MAX_NUM_MIP_MODE, "Error: too many MIP modes" ); @@ -3960,4 +3977,5 @@ void CABACReader::mip_pred_mode( PredictionUnit &pu ) CHECKD(pu.intraDir[CHANNEL_TYPE_LUMA] < 0 || pu.intraDir[CHANNEL_TYPE_LUMA] >= numModes, "Invalid MIP mode"); DTRACE( g_trace_ctx, D_SYNTAX, "mip_pred_mode() pos=(%d,%d) mode=%d\n", pu.lumaPos().x, pu.lumaPos().y, pu.intraDir[CHANNEL_TYPE_LUMA] ); +#endif } diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp index 13ae6e5be9330fef0fdde60bd9f7236bfc2337d1..66c22c9f70b57b90913e33794c27216ef83972b9 100644 --- a/source/Lib/DecoderLib/DecCu.cpp +++ b/source/Lib/DecoderLib/DecCu.cpp @@ -237,7 +237,11 @@ void DecCu::xIntraRecBlk( TransformUnit& tu, const ComponentID compID ) { if( PU::isMIP( pu, chType ) ) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + m_pcIntraPred->initIntraMip( pu, area ); +#else m_pcIntraPred->initIntraMip( pu ); +#endif m_pcIntraPred->predIntraMip( compID, piPred, pu ); } else diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index e2508b372d47dcba440c65cb9b447e157f202cc2..e96a72b0e7378ed0dc7e81d2f9f6f0ebfa31eb55 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -3681,6 +3681,9 @@ void CABACWriter::mip_flag( const CodingUnit& cu ) { return; } +#if JVET_P0803_COMBINED_MIP_CLEANUP + CHECK( cu.lwidth() > MIP_MAX_WIDTH || cu.lheight() > MIP_MAX_HEIGHT, "Error: block size not supported for MIP" ); +#else if( cu.lwidth() > cu.cs->sps->getMaxTbSize() || cu.lheight() > cu.cs->sps->getMaxTbSize()) { return; @@ -3689,6 +3692,7 @@ void CABACWriter::mip_flag( const CodingUnit& cu ) { return; } +#endif unsigned ctxId = DeriveCtx::CtxMipFlag( cu ); m_BinEncoder.encodeBin( cu.mipFlag, Ctx::MipFlag( ctxId ) ); @@ -3709,11 +3713,21 @@ void CABACWriter::mip_pred_modes( const CodingUnit& cu ) void CABACWriter::mip_pred_mode( const PredictionUnit& pu ) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + m_BinEncoder.encodeBinEP( (pu.mipTransposedFlag ? 1 : 0) ); + + const int numModes = getNumModesMip( pu.Y() ); + CHECKD( pu.intraDir[CHANNEL_TYPE_LUMA] < 0 || pu.intraDir[CHANNEL_TYPE_LUMA] >= numModes, "Invalid MIP mode" ); + xWriteTruncBinCode( pu.intraDir[CHANNEL_TYPE_LUMA], numModes ); + + DTRACE( g_trace_ctx, D_SYNTAX, "mip_pred_mode() pos=(%d,%d) mode=%d transposed=%d\n", pu.lumaPos().x, pu.lumaPos().y, pu.intraDir[CHANNEL_TYPE_LUMA], pu.mipTransposedFlag ? 1 : 0 ); +#else const int numModes = getNumModesMip( pu.Y() ); CHECKD( numModes > MAX_NUM_MIP_MODE, "Error: too many MIP modes" ); xWriteTruncBinCode( pu.intraDir[CHANNEL_TYPE_LUMA], numModes ); DTRACE( g_trace_ctx, D_SYNTAX, "mip_pred_mode() pos=(%d,%d) mode=%d\n", pu.lumaPos().x, pu.lumaPos().y, pu.intraDir[CHANNEL_TYPE_LUMA] ); +#endif } void CABACWriter::codeAlfCtuFilterIndex(CodingStructure& cs, uint32_t ctuRsAddr, bool alfEnableLuma) diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp index 71202a6f7f3f80acbabc53b91ad023bacb7debbf..33612acb0cc233fbc7777a2bf7814e1d55e7e236 100644 --- a/source/Lib/EncoderLib/IntraSearch.cpp +++ b/source/Lib/EncoderLib/IntraSearch.cpp @@ -364,8 +364,14 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, //===== determine set of modes to be tested (using prediction signal only) ===== int numModesAvailable = NUM_LUMA_MODE; // total number of Intra modes const bool fastMip = sps.getUseMIP() && m_pcEncCfg->getUseFastMIP(); +#if JVET_P0803_COMBINED_MIP_CLEANUP + CHECK( pu.lwidth() > MIP_MAX_WIDTH || pu.lheight() > MIP_MAX_HEIGHT, "Error: block size not supported for MIP" ); + const bool mipAllowed = sps.getUseMIP() && isLuma(partitioner.chType) && ((cu.lfnstIdx == 0) || allowLfnstWithMip(cu.firstPU->lumaSize())); + const bool testMip = mipAllowed && !(cu.lwidth() > (8 * cu.lheight()) || cu.lheight() > (8 * cu.lwidth())); +#else const bool mipAllowed = sps.getUseMIP() && isLuma(partitioner.chType) && pu.lwidth() <= cu.cs->sps->getMaxTbSize() && pu.lheight() <= cu.cs->sps->getMaxTbSize() && ((cu.lfnstIdx == 0) || allowLfnstWithMip(cu.firstPU->lumaSize())); const bool testMip = mipAllowed && mipModesAvailable(pu.Y()); +#endif static_vector<ModeInfo, FAST_UDI_MAX_RDMODE_NUM> uiRdModeList; @@ -470,8 +476,13 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, DTRACE(g_trace_ctx, D_INTRA_COST, "IntraHAD: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost, uiMode); +#if JVET_P0803_COMBINED_MIP_CLEANUP + updateCandList( ModeInfo( false, false, 0, NOT_INTRA_SUBPARTITIONS, uiMode ), cost, uiRdModeList, CandCostList, numModesForFullRD ); + updateCandList( ModeInfo( false, false, 0, NOT_INTRA_SUBPARTITIONS, uiMode ), double(minSadHad), uiHadModeList, CandHadList, numHadCand ); +#else updateCandList( ModeInfo(false, 0, NOT_INTRA_SUBPARTITIONS, uiMode), cost, uiRdModeList, CandCostList, numModesForFullRD ); updateCandList( ModeInfo(false, 0, NOT_INTRA_SUBPARTITIONS, uiMode), (double)minSadHad, uiHadModeList, CandHadList, numHadCand ); +#endif } if( !sps.getUseMIP() && LFNSTSaveFlag ) { @@ -540,8 +551,13 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, double cost = (double) minSadHad + (double) fracModeBits * sqrtLambdaForFirstPass; +#if JVET_P0803_COMBINED_MIP_CLEANUP + updateCandList( ModeInfo( false, false, 0, NOT_INTRA_SUBPARTITIONS, mode ), cost, uiRdModeList, CandCostList, numModesForFullRD ); + updateCandList( ModeInfo( false, false, 0, NOT_INTRA_SUBPARTITIONS, mode ), double(minSadHad), uiHadModeList, CandHadList, numHadCand ); +#else updateCandList( ModeInfo( false, 0, NOT_INTRA_SUBPARTITIONS, mode ), cost, uiRdModeList, CandCostList, numModesForFullRD ); updateCandList( ModeInfo( false, 0, NOT_INTRA_SUBPARTITIONS, mode ), (double)minSadHad, uiHadModeList, CandHadList, numHadCand ); +#endif bSatdChecked[mode] = true; } @@ -595,8 +611,13 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, uint64_t fracModeBits = xFracModeBitsIntra(pu, mode, CHANNEL_TYPE_LUMA); double cost = (double)minSadHad + (double)fracModeBits * sqrtLambdaForFirstPass; +#if JVET_P0803_COMBINED_MIP_CLEANUP + updateCandList( ModeInfo( false, false, multiRefIdx, NOT_INTRA_SUBPARTITIONS, mode ), cost, uiRdModeList, CandCostList, numModesForFullRD ); + updateCandList( ModeInfo( false, false, multiRefIdx, NOT_INTRA_SUBPARTITIONS, mode ), double(minSadHad), uiHadModeList, CandHadList, numHadCand ); +#else updateCandList( ModeInfo( false, multiRefIdx, NOT_INTRA_SUBPARTITIONS, mode ), cost, uiRdModeList, CandCostList, numModesForFullRD ); updateCandList( ModeInfo( false, multiRefIdx, NOT_INTRA_SUBPARTITIONS, mode ), (double)minSadHad, uiHadModeList, CandHadList, numHadCand ); +#endif } } } @@ -627,10 +648,23 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, double mipHadCost[MAX_NUM_MIP_MODE] = { MAX_DOUBLE }; initIntraPatternChType(cu, pu.Y()); +#if JVET_P0803_COMBINED_MIP_CLEANUP + initIntraMip( pu, pu.Y() ); + + const int transpOff = getNumModesMip( pu.Y() ); + const int numModesFull = (transpOff << 1); + for( uint32_t uiModeFull = 0; uiModeFull < numModesFull; uiModeFull++ ) + { + const bool isTransposed = (uiModeFull >= transpOff ? true : false); + const uint32_t uiMode = (isTransposed ? uiModeFull - transpOff : uiModeFull); + + pu.mipTransposedFlag = isTransposed; +#else initIntraMip( pu ); for (uint32_t uiMode = 0; uiMode < getNumModesMip(pu.Y()); uiMode++) { +#endif pu.intraDir[CHANNEL_TYPE_LUMA] = uiMode; predIntraMip(COMPONENT_Y, piPred, pu); @@ -643,11 +677,19 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, uint64_t fracModeBits = xFracModeBitsIntra(pu, uiMode, CHANNEL_TYPE_LUMA); double cost = double(minSadHad) + double(fracModeBits) * sqrtLambdaForFirstPass; +#if JVET_P0803_COMBINED_MIP_CLEANUP + mipHadCost[uiModeFull] = cost; + DTRACE(g_trace_ctx, D_INTRA_COST, "IntraMIP: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost, uiModeFull); + + updateCandList( ModeInfo( true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, uiMode ), cost, uiRdModeList, CandCostList, numModesForFullRD + 1 ); + updateCandList( ModeInfo( true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, uiMode ), 0.8*double(minSadHad), uiHadModeList, CandHadList, numHadCand ); +#else mipHadCost[uiMode] = cost; DTRACE(g_trace_ctx, D_INTRA_COST, "IntraMIP: %u, %llu, %f (%d)\n", minSadHad, fracModeBits, cost, uiMode); updateCandList(ModeInfo(true, 0, NOT_INTRA_SUBPARTITIONS, uiMode), cost, uiRdModeList, CandCostList, numModesForFullRD + 1); updateCandList(ModeInfo(true, 0, NOT_INTRA_SUBPARTITIONS, uiMode), 0.8*double(minSadHad), uiHadModeList, CandHadList, numHadCand); +#endif } const double thresholdHadCost = 1.0 + 1.4 / sqrt((double)(pu.lwidth()*pu.lheight())); @@ -688,7 +730,11 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, for( int j = 0; j < numCand; j++ ) { bool mostProbableModeIncluded = false; +#if JVET_P0803_COMBINED_MIP_CLEANUP + ModeInfo mostProbableMode( false, false, 0, NOT_INTRA_SUBPARTITIONS, uiPreds[j] ); +#else ModeInfo mostProbableMode( false, 0, NOT_INTRA_SUBPARTITIONS, uiPreds[j] ); +#endif for( int i = 0; i < numModesForFullRD; i++ ) @@ -708,7 +754,11 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, for (int j = 0; j < numCand; j++) { bool mostProbableModeIncluded = false; +#if JVET_P0803_COMBINED_MIP_CLEANUP + ModeInfo mostProbableMode( false, false, 0, NOT_INTRA_SUBPARTITIONS, uiPreds[j] ); +#else ModeInfo mostProbableMode(false, 0, NOT_INTRA_SUBPARTITIONS, uiPreds[j]); +#endif for (int i = 0; i < m_ispCandListHor.size(); i++) { @@ -826,7 +876,11 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, // we reserve positions for ISP in the common full RD list const int maxNumRDModesISP = 16; for (int i = 0; i < maxNumRDModesISP; i++) +#if JVET_P0803_COMBINED_MIP_CLEANUP + uiRdModeList.push_back( ModeInfo( false, false, 0, INTRA_SUBPARTITIONS_RESERVED, 0 ) ); +#else uiRdModeList.push_back(ModeInfo(false, 0, INTRA_SUBPARTITIONS_RESERVED, 0)); +#endif } //===== check modes (using r-d costs) ===== @@ -844,6 +898,7 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, csTemp->picture = cs.picture; csBest->picture = cs.picture; +#if !JVET_P0803_COMBINED_MIP_CLEANUP static_vector<int, FAST_UDI_MAX_RDMODE_NUM> rdModeIdxList; if (testMip) { @@ -886,6 +941,7 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, uiRdModeList[i] = rdModeListTemp[i]; } } +#endif // just to be sure numModesForFullRD = ( int ) uiRdModeList.size(); @@ -903,8 +959,15 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, { cu.bdpcmMode = -mode; +#if JVET_P0803_COMBINED_MIP_CLEANUP + uiOrgMode = ModeInfo( false, false, 0, NOT_INTRA_SUBPARTITIONS, cu.bdpcmMode == 2 ? VER_IDX : HOR_IDX ); +#else uiOrgMode = ModeInfo(false, 0, NOT_INTRA_SUBPARTITIONS, cu.bdpcmMode == 2 ? VER_IDX : HOR_IDX); +#endif cu.mipFlag = uiOrgMode.mipFlg; +#if JVET_P0803_COMBINED_MIP_CLEANUP + pu.mipTransposedFlag = uiOrgMode.mipTrFlg; +#endif cu.ispMode = uiOrgMode.ispMod; pu.multiRefIdx = uiOrgMode.mRefId; pu.intraDir[CHANNEL_TYPE_LUMA] = uiOrgMode.modeId; @@ -924,6 +987,9 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, } uiOrgMode = uiRdModeList[mode]; cu.mipFlag = uiOrgMode.mipFlg; +#if JVET_P0803_COMBINED_MIP_CLEANUP + pu.mipTransposedFlag = uiOrgMode.mipTrFlg; +#endif cu.ispMode = uiOrgMode.ispMod; pu.multiRefIdx = uiOrgMode.mRefId; pu.intraDir[CHANNEL_TYPE_LUMA] = uiOrgMode.modeId; @@ -964,7 +1030,11 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, if (!cu.ispMode && !cu.mtsFlag && !cu.lfnstIdx && !cu.bdpcmMode && !pu.multiRefIdx && !cu.mipFlag && testISP) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + m_regIntraRDListWithCosts.push_back( ModeInfoWithCost( cu.mipFlag, pu.mipTransposedFlag, pu.multiRefIdx, cu.ispMode, uiOrgMode.modeId, csTemp->cost ) ); +#else m_regIntraRDListWithCosts.push_back(ModeInfoWithCost(cu.mipFlag, pu.multiRefIdx, cu.ispMode, uiOrgMode.modeId, csTemp->cost)); +#endif } if( cu.ispMode && !csTemp->cus[0]->firstTU->cbf[COMPONENT_Y] ) @@ -977,7 +1047,11 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, if( sps.getUseLFNST() && mtsUsageFlag == 1 && !cu.ispMode && mode >= 0 ) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + m_modeCostStore[lfnstIdx][mode] = tmpValidReturn ? csTemp->cost : (MAX_DOUBLE / 2.0); //(MAX_DOUBLE / 2.0) ?? +#else m_modeCostStore[ lfnstIdx ][ testMip ? rdModeIdxList[ mode ] : mode ] = tmpValidReturn ? csTemp->cost : ( MAX_DOUBLE / 2.0 ); //(MAX_DOUBLE / 2.0) ?? +#endif } DTRACE(g_trace_ctx, D_INTRA_COST, "IntraCost T [x=%d,y=%d,w=%d,h=%d] %f (%d,%d,%d,%d,%d,%d) \n", cu.blocks[0].x, @@ -1045,6 +1119,9 @@ bool IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner, { //=== update PU data ==== cu.mipFlag = uiBestPUMode.mipFlg; +#if JVET_P0803_COMBINED_MIP_CLEANUP + pu.mipTransposedFlag = uiBestPUMode.mipTrFlg; +#endif pu.multiRefIdx = uiBestPUMode.mRefId; pu.intraDir[ CHANNEL_TYPE_LUMA ] = uiBestPUMode.modeId; cu.bdpcmMode = bestBDPCMMode; @@ -2363,6 +2440,9 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp { if( PU::isMIP( pu, chType ) ) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + initIntraMip( pu, area ); +#endif predIntraMip( compID, piPred, pu ); } else @@ -3845,10 +3925,18 @@ void IntraSearch::reduceHadCandList(static_vector<T, N>& candModeList, static_ve if ((pu.lwidth() > 8 && pu.lheight() > 8)) { // Sort MIP candidates by Hadamard cost +#if JVET_P0803_COMBINED_MIP_CLEANUP + const int transpOff = getNumModesMip( pu.Y() ); +#else const int transpOff = getNumModesMip(pu.Y()) / 2; +#endif static_vector<uint8_t, FAST_UDI_MAX_RDMODE_NUM> sortedMipModes(0); static_vector<double, FAST_UDI_MAX_RDMODE_NUM> sortedMipCost(0); +#if JVET_P0803_COMBINED_MIP_CLEANUP + for( uint8_t mode : { 0, 1, 2 } ) +#else for (uint8_t mode : { 3, 4, 5 }) +#endif { uint8_t candMode = mode + uint8_t((mipHadCost[mode + transpOff] < mipHadCost[mode]) ? transpOff : 0); updateCandList(candMode, mipHadCost[candMode], sortedMipModes, sortedMipCost, 3); @@ -3858,7 +3946,13 @@ void IntraSearch::reduceHadCandList(static_vector<T, N>& candModeList, static_ve const int modeListSize = int(tempRdModeList.size()); for (int idx = 0; idx < 3; idx++) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + const bool isTransposed = (sortedMipModes[idx] >= transpOff ? true : false); + const uint32_t mipIdx = (isTransposed ? sortedMipModes[idx] - transpOff : sortedMipModes[idx]); + const ModeInfo mipMode( true, isTransposed, 0, NOT_INTRA_SUBPARTITIONS, mipIdx ); +#else const ModeInfo mipMode(true, 0, NOT_INTRA_SUBPARTITIONS, sortedMipModes[idx]); +#endif bool alreadyIncluded = false; for (int modeListIdx = 0; modeListIdx < modeListSize; modeListIdx++) { @@ -4080,12 +4174,20 @@ void IntraSearch::xSortISPCandList(double bestCostSoFar, double bestNonISPCost) ModeInfo refMode = origHadList.at(0); auto* destListPtr = &m_ispCandListHor; // 1) Planar +#if JVET_P0803_COMBINED_MIP_CLEANUP + destListPtr->push_back( ModeInfo( refMode.mipFlg, refMode.mipTrFlg, refMode.mRefId, refMode.ispMod, mode1 ) ); +#else destListPtr->push_back(ModeInfo(refMode.mipFlg, refMode.mRefId, refMode.ispMod, mode1)); +#endif modeIsInList[mode1] = true; // 2) Best angle in regular intra if (mode2 != -1) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + destListPtr->push_back( ModeInfo( refMode.mipFlg, refMode.mipTrFlg, refMode.mRefId, refMode.ispMod, mode2 ) ); +#else destListPtr->push_back(ModeInfo(refMode.mipFlg, refMode.mRefId, refMode.ispMod, mode2)); +#endif modeIsInList[mode2] = true; } // 3) Remaining regular intra modes that were full RD tested (except DC, which is added after the angles from regular intra) @@ -4097,7 +4199,11 @@ void IntraSearch::xSortISPCandList(double bestCostSoFar, double bestNonISPCost) { if (currentMode > DC_IDX) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + destListPtr->push_back( ModeInfo( refMode.mipFlg, refMode.mipTrFlg, refMode.mRefId, refMode.ispMod, currentMode ) ); +#else destListPtr->push_back(ModeInfo(refMode.mipFlg, refMode.mRefId, refMode.ispMod, currentMode)); +#endif modeIsInList[currentMode] = true; } else if (currentMode == DC_IDX) @@ -4109,7 +4215,11 @@ void IntraSearch::xSortISPCandList(double bestCostSoFar, double bestNonISPCost) // 4) DC is added after the angles from regular intra if (dcModeIndex != -1) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + destListPtr->push_back( ModeInfo( refMode.mipFlg, refMode.mipTrFlg, refMode.mRefId, refMode.ispMod, DC_IDX ) ); +#else destListPtr->push_back(ModeInfo(refMode.mipFlg, refMode.mRefId, refMode.ispMod, DC_IDX)); +#endif modeIsInList[DC_IDX] = true; } @@ -4126,7 +4236,11 @@ void IntraSearch::xSortISPCandList(double bestCostSoFar, double bestNonISPCost) } if (!modeIsInList[origHadList.at(k).modeId]) { +#if JVET_P0803_COMBINED_MIP_CLEANUP + destListPtr->push_back( ModeInfo( refMode.mipFlg, refMode.mipTrFlg, refMode.mRefId, refMode.ispMod, origHadList.at(k).modeId ) ); +#else destListPtr->push_back(ModeInfo(refMode.mipFlg, refMode.mRefId, refMode.ispMod, origHadList.at(k).modeId)); +#endif newModesAdded++; } } diff --git a/source/Lib/EncoderLib/IntraSearch.h b/source/Lib/EncoderLib/IntraSearch.h index ed193dcd6b341b52ad7d8a0cb24baf51139e24f4..778a70e89298bc55e8eaf8955b27cbb57b576e22 100644 --- a/source/Lib/EncoderLib/IntraSearch.h +++ b/source/Lib/EncoderLib/IntraSearch.h @@ -186,20 +186,34 @@ private: struct ModeInfo { bool mipFlg; // CU::mipFlag +#if JVET_P0803_COMBINED_MIP_CLEANUP + bool mipTrFlg; // PU::mipTransposedFlag +#endif int mRefId; // PU::multiRefIdx uint8_t ispMod; // CU::ispMode uint32_t modeId; // PU::intraDir[CHANNEL_TYPE_LUMA] +#if JVET_P0803_COMBINED_MIP_CLEANUP + ModeInfo() : mipFlg(false), mipTrFlg(false), mRefId(0), ispMod(NOT_INTRA_SUBPARTITIONS), modeId(0) {} + ModeInfo(const bool mipf, const bool miptf, const int mrid, const uint8_t ispm, const uint32_t mode) : mipFlg(mipf), mipTrFlg(miptf), mRefId(mrid), ispMod(ispm), modeId(mode) {} + bool operator==(const ModeInfo cmp) const { return (mipFlg == cmp.mipFlg && mipTrFlg == cmp.mipTrFlg && mRefId == cmp.mRefId && ispMod == cmp.ispMod && modeId == cmp.modeId); } +#else ModeInfo() : mipFlg(false), mRefId(0), ispMod(NOT_INTRA_SUBPARTITIONS), modeId(0) {} ModeInfo(const bool mipf, const int mrid, const uint8_t ispm, const uint32_t mode) : mipFlg(mipf), mRefId(mrid), ispMod(ispm), modeId(mode) {} bool operator==(const ModeInfo cmp) const { return (mipFlg == cmp.mipFlg && mRefId == cmp.mRefId && ispMod == cmp.ispMod && modeId == cmp.modeId); } +#endif }; struct ModeInfoWithCost : public ModeInfo { double rdCost; ModeInfoWithCost() : ModeInfo(), rdCost(MAX_DOUBLE) {} +#if JVET_P0803_COMBINED_MIP_CLEANUP + ModeInfoWithCost(const bool mipf, const bool miptf, const int mrid, const uint8_t ispm, const uint32_t mode, double cost) : ModeInfo(mipf, miptf, mrid, ispm, mode), rdCost(cost) {} + bool operator==(const ModeInfoWithCost cmp) const { return (mipFlg == cmp.mipFlg && mipTrFlg == cmp.mipTrFlg && mRefId == cmp.mRefId && ispMod == cmp.ispMod && modeId == cmp.modeId && rdCost == cmp.rdCost); } +#else ModeInfoWithCost(const bool mipf, const int mrid, const uint8_t ispm, const uint32_t mode, double cost) : ModeInfo(mipf, mrid, ispm, mode), rdCost(cost) {} bool operator==(const ModeInfoWithCost cmp) const { return (mipFlg == cmp.mipFlg && mRefId == cmp.mRefId && ispMod == cmp.ispMod && modeId == cmp.modeId && rdCost == cmp.rdCost); } +#endif static bool compareModeInfoWithCost(ModeInfoWithCost a, ModeInfoWithCost b) { return a.rdCost < b.rdCost; } };