diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 7f40bc0665b59f4b7a77c9263995244be772ddad..f029e34f868addd75ce561bb5ce3b24e306f71a9 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1959,7 +1959,19 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) } #endif - + if (m_chromaFormatIDC != CHROMA_420) + { + if (!m_horCollocatedChromaFlag) + { + msg(WARNING, "\nWARNING: HorCollocatedChroma is forced to 1 for chroma formats other than 4:2:0\n"); + m_horCollocatedChromaFlag = true; + } + if (!m_verCollocatedChromaFlag) + { + msg(WARNING, "\nWARNING: VerCollocatedChroma is forced to 1 for chroma formats other than 4:2:0\n"); + m_verCollocatedChromaFlag = true; + } + } #if JVET_O0756_CONFIG_HDRMETRICS && !JVET_O0756_CALCULATE_HDRMETRICS if ( m_calculateHdrMetrics == true) { diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp index 3a24c156f18d8b2ccbc9da9a142281277bbe5a07..1b148e41e9a2fab085284a5bf5ebf042ca27a8af 100644 --- a/source/Lib/CommonLib/IntraPrediction.cpp +++ b/source/Lib/CommonLib/IntraPrediction.cpp @@ -1350,7 +1350,6 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom int logSubHeightC = getChannelTypeScaleY(CHANNEL_TYPE_CHROMA, pu.chromaFormat); int iRecStride2 = iRecStride << logSubHeightC; - const int mult = 1 << logSubWidthC ; const CodingUnit& lumaCU = isChroma( pu.chType ) ? *pu.cs->picture->cs->getCU( lumaArea.pos(), CH_L ) : *pu.cu; const CodingUnit& cu = *pu.cu; @@ -1385,24 +1384,24 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom int avaiLeftBelowUnits = 0; bool bNeighborFlags[4 * MAX_NUM_PART_IDXS_IN_CTU_WIDTH + 1]; memset(bNeighborFlags, 0, totalUnits); - bool bAboveAvaillable, bLeftAvaillable; + bool aboveIsAvailable, leftIsAvailable; int availlableUnit = isLeftAvailable( isChroma( pu.chType ) ? cu : lumaCU, toChannelType( area.compID ), area.pos(), iLeftUnits, iUnitHeight, ( bNeighborFlags + iLeftUnits + leftBelowUnits - 1 ) ); - bLeftAvaillable = availlableUnit == iTUHeightInUnits; + leftIsAvailable = availlableUnit == iTUHeightInUnits; availlableUnit = isAboveAvailable( isChroma( pu.chType ) ? cu : lumaCU, toChannelType( area.compID ), area.pos(), iAboveUnits, iUnitWidth, ( bNeighborFlags + iLeftUnits + leftBelowUnits + 1 ) ); - bAboveAvaillable = availlableUnit == iTUWidthInUnits; + aboveIsAvailable = availlableUnit == iTUWidthInUnits; - if (bLeftAvaillable) // if left is not available, then the below left is not available + if (leftIsAvailable) // if left is not available, then the below left is not available { avaiLeftBelowUnits = isBelowLeftAvailable(isChroma(pu.chType) ? cu : lumaCU, toChannelType(area.compID), area.bottomLeftComp(area.compID), leftBelowUnits, iUnitHeight, (bNeighborFlags + leftBelowUnits - 1)); } - if (bAboveAvaillable) // if above is not available, then the above right is not available. + if (aboveIsAvailable) // if above is not available, then the above right is not available. { avaiAboveRightUnits = isAboveRightAvailable(isChroma(pu.chType) ? cu : lumaCU, toChannelType(area.compID), area.topRightComp(area.compID), aboveRightUnits, iUnitWidth, (bNeighborFlags + iLeftUnits + leftBelowUnits + iAboveUnits + 1)); } @@ -1410,31 +1409,9 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom Pel* pDst = nullptr; Pel const* piSrc = nullptr; - bool isFirstRowOfCtu = ( lumaArea.y & ((pu.cs->sps)->getCTUSize() - 1) ) == 0; - const int strOffset = (CHROMA_444 == pu.chromaFormat) ? 0 : iRecStride; - int c0_3tap = 2, c1_3tap = 1, c2_3tap = 1, offset_3tap = 2, shift_3tap = 2; //sum = 4 - int c0_5tap = 1, c1_5tap = 4, c2_5tap = 1, c3_5tap = 1, c4_5tap = 1, offset_5tap = 4, shift_5tap = 3; //sum = 8 - int c0_6tap = 2, c1_6tap = 1, c2_6tap = 1, c3_6tap = 2, c4_6tap = 1, c5_6tap = 1, offset_6tap = 4, shift_6tap = 3; //sum = 8 + bool isFirstRowOfCtu = (lumaArea.y & ((pu.cs->sps)->getCTUSize() - 1)) == 0; - switch (pu.chromaFormat) - { - case CHROMA_422: //overwrite filter coefficient values for 422 - c0_3tap = 2, c1_3tap = 1, c2_3tap = 1, offset_3tap = 2, shift_3tap = 2; //sum = 4 - c0_5tap = 0, c1_5tap = 1, c2_5tap = 0, c3_5tap = 0, c4_5tap = 0, offset_5tap = 0, shift_5tap = 0; //sum = 1 - c0_6tap = 2, c1_6tap = 1, c2_6tap = 1, c3_6tap = 0, c4_6tap = 0, c5_6tap = 0, offset_6tap = 2, shift_6tap = 2; //sum = 4 - break; - - case CHROMA_444: //overwrite filter coefficient values for 422 - c0_3tap = 1, c1_3tap = 0, c2_3tap = 0, offset_3tap = 0, shift_3tap = 0; //sum = 1 - c0_5tap = 0, c1_5tap = 1, c2_5tap = 0, c3_5tap = 0, c4_5tap = 0, offset_5tap = 0, shift_5tap = 0; //sum = 1 - c0_6tap = 1, c1_6tap = 0, c2_6tap = 0, c3_6tap = 0, c4_6tap = 0, c5_6tap = 0, offset_6tap = 0, shift_6tap = 0; //sum = 1 - break; - - default: - break; - } - - if( bAboveAvaillable ) + if (aboveIsAvailable) { pDst = pDst0 - iDstStride; int addedAboveRight = 0; @@ -1444,63 +1421,58 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom } for (int i = 0; i < uiCWidth + addedAboveRight; i++) { - if (isFirstRowOfCtu) + const bool leftPadding = i == 0 && !leftIsAvailable; + if (pu.chromaFormat == CHROMA_444) { piSrc = pRecSrc0 - iRecStride; + pDst[i] = piSrc[i]; + } + else if (isFirstRowOfCtu) + { + piSrc = pRecSrc0 - iRecStride; + pDst[i] = (piSrc[2 * i] * 2 + piSrc[2 * i - (leftPadding ? 0 : 1)] + piSrc[2 * i + 1] + 2) >> 2; + } + else if (pu.chromaFormat == CHROMA_422) + { + piSrc = pRecSrc0 - iRecStride2; - if ((i == 0 && !bLeftAvaillable) || (i == uiCWidth + addedAboveRight - 1 + logSubWidthC)) - { - pDst[i] = (piSrc[mult * i] * c0_3tap + piSrc[mult * i] * c1_3tap + piSrc[mult * i + 1] * c2_3tap + offset_3tap) >> shift_3tap; - } - else - { - pDst[i] = (piSrc[mult * i] * c0_3tap + piSrc[mult * i - 1] * c1_3tap + piSrc[mult * i + 1] * c2_3tap + offset_3tap) >> shift_3tap; - } + int s = 2; + s += piSrc[2 * i] * 2; + s += piSrc[2 * i - (leftPadding ? 0 : 1)]; + s += piSrc[2 * i + 1]; + pDst[i] = s >> 2; } - else if( pu.cs->sps->getCclmCollocatedChromaFlag() ) + else if (pu.cs->sps->getCclmCollocatedChromaFlag()) { piSrc = pRecSrc0 - iRecStride2; - if ((i == 0 && !bLeftAvaillable) || (i == uiCWidth + addedAboveRight - 1 + logSubWidthC)) - { - pDst[i] = (piSrc[mult * i - strOffset] * c0_5tap - + piSrc[mult * i] * c1_5tap + piSrc[mult * i] * c2_5tap + piSrc[mult * i + 1] * c3_5tap - + piSrc[mult * i + strOffset] * c4_5tap - + offset_5tap) >> shift_5tap; - } - else - { - pDst[i] = (piSrc[mult * i - strOffset] * c0_5tap - + piSrc[mult * i] * c1_5tap + piSrc[mult * i - 1] * c2_5tap + piSrc[mult * i + 1] * c3_5tap - + piSrc[mult * i + strOffset] * c4_5tap - + offset_5tap) >> shift_5tap; - } + int s = 4; + s += piSrc[2 * i - iRecStride]; + s += piSrc[2 * i] * 4; + s += piSrc[2 * i - (leftPadding ? 0 : 1)]; + s += piSrc[2 * i + 1]; + s += piSrc[2 * i + iRecStride]; + pDst[i] = s >> 3; } else { piSrc = pRecSrc0 - iRecStride2; - - if ((i == 0 && !bLeftAvaillable) || (i == uiCWidth + addedAboveRight - 1 + logSubWidthC)) - { - pDst[i] = ((piSrc[mult * i] * c0_6tap + piSrc[mult * i] * c1_6tap + piSrc[mult * i + 1] * c2_6tap) - + (piSrc[mult * i + strOffset] * c3_6tap + piSrc[mult * i + strOffset] * c4_6tap + piSrc[mult * i + 1 + strOffset] * c5_6tap) - + offset_6tap) >> shift_6tap; - } - else - { - pDst[i] = ((piSrc[mult * i] * c0_6tap + piSrc[mult * i - 1] * c1_6tap + piSrc[mult * i + 1] * c2_6tap) - + (piSrc[mult * i + strOffset] * c3_6tap + piSrc[mult * i - 1 + strOffset] * c4_6tap + piSrc[mult * i + 1 + strOffset] * c5_6tap) - + offset_6tap) >> shift_6tap; - } + int s = 4; + s += piSrc[2 * i] * 2; + s += piSrc[2 * i + 1]; + s += piSrc[2 * i - (leftPadding ? 0 : 1)]; + s += piSrc[2 * i + iRecStride] * 2; + s += piSrc[2 * i + 1 + iRecStride]; + s += piSrc[2 * i + iRecStride - (leftPadding ? 0 : 1)]; + pDst[i] = s >> 3; } } } - if( bLeftAvaillable ) + if (leftIsAvailable) { pDst = pDst0 - 1; - - piSrc = pRecSrc0 - 2 - logSubWidthC; + piSrc = pRecSrc0 - 1 - logSubWidthC; int addedLeftBelow = 0; if ((curChromaMode == MDLM_L_IDX) || (curChromaMode == MDLM_T_IDX)) @@ -1510,28 +1482,40 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom for (int j = 0; j < uiCHeight + addedLeftBelow; j++) { - if( pu.cs->sps->getCclmCollocatedChromaFlag() ) + if (pu.chromaFormat == CHROMA_444) { - if ((j == 0 && !bAboveAvaillable) || (j == uiCHeight + addedLeftBelow - 1 + logSubWidthC)) - { - pDst[0] = ( piSrc[1 ] * c0_5tap - + piSrc[1 ] * c1_5tap + piSrc[0] * c2_5tap + piSrc[2] * c3_5tap - + piSrc[1 + strOffset] * c4_5tap - + offset_5tap ) >> shift_5tap; - } - else - { - pDst[0] = ( piSrc[1 - strOffset] * c0_5tap - + piSrc[1 ] * c1_5tap + piSrc[0] * c2_5tap + piSrc[2] * c3_5tap - + piSrc[1 + strOffset] * c4_5tap - + offset_5tap ) >> shift_5tap; - } + pDst[0] = piSrc[0]; + } + else if (pu.chromaFormat == CHROMA_422) + { + int s = 2; + s += piSrc[0] * 2; + s += piSrc[-1]; + s += piSrc[1]; + pDst[0] = s >> 2; + } + else if (pu.cs->sps->getCclmCollocatedChromaFlag()) + { + const bool abovePadding = j == 0 && !aboveIsAvailable; + + int s = 4; + s += piSrc[-(abovePadding ? 0 : iRecStride)]; + s += piSrc[0] * 4; + s += piSrc[-1]; + s += piSrc[1]; + s += piSrc[iRecStride]; + pDst[0] = s >> 3; } else { - pDst[0] = ((piSrc[1] * c0_6tap + piSrc[0] * c1_6tap + piSrc[2] * c2_6tap) - + (piSrc[1 + strOffset] * c3_6tap + piSrc[strOffset] * c4_6tap + piSrc[2 + strOffset] * c5_6tap) - + offset_6tap) >> shift_6tap; + int s = 4; + s += piSrc[0] * 2; + s += piSrc[1]; + s += piSrc[-1]; + s += piSrc[iRecStride] * 2; + s += piSrc[iRecStride + 1]; + s += piSrc[iRecStride - 1]; + pDst[0] = s >> 3; } piSrc += iRecStride2; @@ -1544,71 +1528,46 @@ void IntraPrediction::xGetLumaRecPixels(const PredictionUnit &pu, CompArea chrom { for( int i = 0; i < uiCWidth; i++ ) { - if( pu.cs->sps->getCclmCollocatedChromaFlag() ) + if (pu.chromaFormat == CHROMA_444) { - if( i == 0 && !bLeftAvaillable ) - { - if ( j == 0 && !bAboveAvaillable ) - { - pDst0[i] = (pRecSrc0[mult * i] * c0_5tap - + pRecSrc0[mult * i] * c1_5tap + pRecSrc0[mult * i] * c2_5tap + pRecSrc0[mult * i + 1] * c3_5tap - + pRecSrc0[mult * i + strOffset] * c4_5tap - + offset_5tap) >> shift_5tap; - } - else - { - pDst0[i] = (pRecSrc0[mult * i - strOffset] * c0_5tap - + pRecSrc0[mult * i] * c1_5tap + pRecSrc0[mult * i] * c2_5tap + pRecSrc0[mult * i + 1] * c3_5tap - + pRecSrc0[mult * i + strOffset] * c4_5tap - + offset_5tap) >> shift_5tap; - } - } - else if ( j == 0 && !bAboveAvaillable ) - { - pDst0[i] = (pRecSrc0[mult * i] * c0_5tap - + pRecSrc0[mult * i] * c1_5tap + pRecSrc0[mult * i - 1] * c2_5tap + pRecSrc0[mult * i + 1] * c3_5tap - + pRecSrc0[mult * i + strOffset] * c4_5tap - + offset_5tap) >> shift_5tap; - } - else - { - pDst0[i] = (pRecSrc0[mult * i - strOffset] * c0_5tap - + pRecSrc0[mult * i] * c1_5tap + pRecSrc0[mult * i - 1] * c2_5tap + pRecSrc0[mult * i + 1] * c3_5tap - + pRecSrc0[mult * i + strOffset] * c4_5tap - + offset_5tap) >> shift_5tap; - } + pDst0[i] = pRecSrc0[i]; } - else + else if (pu.chromaFormat == CHROMA_422) { + const bool leftPadding = i == 0 && !leftIsAvailable; - if ((i == 0 && !bLeftAvaillable) || (i == uiCWidth - 1 + logSubWidthC)) - { - int s = offset_6tap; - s += pRecSrc0[mult * i] * c0_6tap; - s += pRecSrc0[mult * i + 1] * c1_6tap; - s += pRecSrc0[mult * i] * c2_6tap; - if (pu.chromaFormat == CHROMA_420) - { - s += pRecSrc0[mult * i + strOffset] * c3_6tap; - s += pRecSrc0[mult * i + 1 + strOffset] * c4_6tap; - s += pRecSrc0[mult * i + strOffset] * c5_6tap; - } - pDst0[i] = s >> shift_6tap; - } - else - { - int s = offset_6tap; - s += pRecSrc0[mult * i] * c0_6tap; - s += pRecSrc0[mult * i + 1] * c1_6tap; - s += pRecSrc0[mult * i - 1] * c2_6tap; - if (pu.chromaFormat == CHROMA_420) - { - s += pRecSrc0[mult * i + strOffset] * c3_6tap; - s += pRecSrc0[mult * i + 1 + strOffset] * c4_6tap; - s += pRecSrc0[mult * i - 1 + strOffset] * c5_6tap; - } - pDst0[i] = s >> shift_6tap; - } + int s = 2; + s += pRecSrc0[2 * i] * 2; + s += pRecSrc0[2 * i - (leftPadding ? 0 : 1)]; + s += pRecSrc0[2 * i + 1]; + pDst0[i] = s >> 2; + } + else if (pu.cs->sps->getCclmCollocatedChromaFlag()) + { + const bool leftPadding = i == 0 && !leftIsAvailable; + const bool abovePadding = j == 0 && !aboveIsAvailable; + + int s = 4; + s += pRecSrc0[2 * i - (abovePadding ? 0 : iRecStride)]; + s += pRecSrc0[2 * i] * 4; + s += pRecSrc0[2 * i - (leftPadding ? 0 : 1)]; + s += pRecSrc0[2 * i + 1]; + s += pRecSrc0[2 * i + iRecStride]; + pDst0[i] = s >> 3; + } + else + { + CHECK(pu.chromaFormat != CHROMA_420, "Chroma format must be 4:2:0 for vertical filtering"); + const bool leftPadding = i == 0 && !leftIsAvailable; + + int s = 4; + s += pRecSrc0[2 * i] * 2; + s += pRecSrc0[2 * i + 1]; + s += pRecSrc0[2 * i - (leftPadding ? 0 : 1)]; + s += pRecSrc0[2 * i + iRecStride] * 2; + s += pRecSrc0[2 * i + 1 + iRecStride]; + s += pRecSrc0[2 * i + iRecStride - (leftPadding ? 0 : 1)]; + pDst0[i] = s >> 3; } } diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 626a5500063fd62bc3c6a48ae5cf571b6b976687..875aab8e0479a5eae14d9352fad1908023781350 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -1807,6 +1807,11 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) READ_FLAG( uiCode, "sps_chroma_horizontal_collocated_flag" ); pcSPS->setHorCollocatedChromaFlag( uiCode != 0 ); READ_FLAG( uiCode, "sps_chroma_vertical_collocated_flag" ); pcSPS->setVerCollocatedChromaFlag( uiCode != 0 ); } + else + { + pcSPS->setHorCollocatedChromaFlag(true); + pcSPS->setVerCollocatedChromaFlag(true); + } READ_FLAG( uiCode, "sps_mts_enabled_flag" ); pcSPS->setUseMTS ( uiCode != 0 ); if ( pcSPS->getUseMTS() ) diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 468c2e737ae8f95227d1c7e3dc759bc374460e6e..4786fd0080224638244d8ad4a5bf7aeea9b939c3 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -1101,6 +1101,11 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) WRITE_FLAG( pcSPS->getHorCollocatedChromaFlag() ? 1 : 0, "sps_chroma_horizontal_collocated_flag" ); WRITE_FLAG( pcSPS->getVerCollocatedChromaFlag() ? 1 : 0, "sps_chroma_vertical_collocated_flag" ); } + else + { + CHECK(pcSPS->getHorCollocatedChromaFlag() != 1, "Invalid value for horizontal collocated chroma flag"); + CHECK(pcSPS->getVerCollocatedChromaFlag() != 1, "Invalid value for vertical collocated chroma flag"); + } WRITE_FLAG( pcSPS->getUseMTS() ? 1 : 0, "sps_mts_enabled_flag" ); if ( pcSPS->getUseMTS() )