diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index b5aa741db6e2323835709869b5aebab8d94ee766..27f3e8b61be1f6d33bf4a4107c9ae9cc5a8a761c 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -819,9 +819,9 @@ void EncApp::xInitLibCfg() m_cEncLib.setBIFQPOffset ( m_BIFQPOffset ); #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - m_cEncLib.setUseCBIF ( m_CBIF ); - m_cEncLib.setCBIFStrength ( m_CBIFStrength ); - m_cEncLib.setCBIFQPOffset ( m_CBIFQPOffset ); + m_cEncLib.setUseChromaBIF ( m_chromaBIF ); + m_cEncLib.setChromaBIFStrength ( m_chromaBIFStrength ); + m_cEncLib.setChromaBIFQPOffset ( m_chromaBIFQPOffset ); #endif // ADD_NEW_TOOL : (encoder app) add setting of tool enabling flags and associated parameters here diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index b0e1889da73c90d189e7c72f108c7ced5c3cff90..c8d6da6e65ec00998b51e8729f425df01bcdaebc 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -1069,9 +1069,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("BIFQPOffset", m_BIFQPOffset, 0, "bilateral filter QP offset (0: no offset) [default: 0]") #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - ("CBIF", m_CBIF, true, "chroma bilateral filter (0: off, 1:on) [default: on]") - ("CBIFStrength", m_CBIFStrength, 1u, "chroma bilateral filter strength (0: half, 1: full, 2: double) [default: full]") - ("CBIFQPOffset", m_CBIFQPOffset, 0, "chroma bilateral filter QP offset (0: no offset) [default: 0]") + ("ChromaBIF", m_chromaBIF, true, "chroma bilateral filter (0: off, 1:on) [default: on]") + ("ChromaBIFStrength", m_chromaBIFStrength, 1u, "chroma bilateral filter strength (0: half, 1: full, 2: double) [default: full]") + ("ChromaBIFQPOffset", m_chromaBIFQPOffset, 0, "chroma bilateral filter QP offset (0: no offset) [default: 0]") #endif // ADD_NEW_TOOL : (encoder app) add parsing parameters here ( "VirtualBoundariesPresentInSPSFlag", m_virtualBoundariesPresentFlag, true, "Virtual Boundary position information is signalled in SPS or PH (1:SPS, 0:PH) [default: on]" ) @@ -4403,9 +4403,9 @@ void EncAppCfg::xPrintParameter() msg( VERBOSE, "BIFQPOffset:%d ", m_BIFQPOffset); #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - msg( VERBOSE, "CBIF:%d ", m_CBIF); - msg( VERBOSE, "CBIFStrength:%d ", m_CBIFStrength); - msg( VERBOSE, "CBIFQPOffset:%d ", m_CBIFQPOffset); + msg( VERBOSE, "ChromaBIF:%d ", m_chromaBIF); + msg( VERBOSE, "ChromaBIFStrength:%d ", m_chromaBIFStrength); + msg( VERBOSE, "ChromaBIFQPOffset:%d ", m_chromaBIFQPOffset); #endif // ADD_NEW_TOOL (add some output indicating the usage of tools) msg( VERBOSE, "VirtualBoundariesEnabledFlag:%d ", m_virtualBoundariesEnabledFlag ); diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 5349b4a341fef38faf48757a7d6b9814ddfd3581..46d1f11fc13b07c325d6cfe5c20fa26db5186b43 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -437,9 +437,9 @@ protected: int m_BIFQPOffset; /// Bilateral QP offset #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - bool m_CBIF; - unsigned m_CBIFStrength; - int m_CBIFQPOffset; + bool m_chromaBIF; + unsigned m_chromaBIFStrength; + int m_chromaBIFQPOffset; #endif // ADD_NEW_TOOL : (encoder app) add tool enabling flags and associated parameters here diff --git a/source/Lib/CommonLib/BilateralFilter.cpp b/source/Lib/CommonLib/BilateralFilter.cpp index f36751c882e56124238b0ed118e94488b81b6d26..3520525c0f2ff72c95a52329998e7044a3c9d4c2 100755 --- a/source/Lib/CommonLib/BilateralFilter.cpp +++ b/source/Lib/CommonLib/BilateralFilter.cpp @@ -597,7 +597,7 @@ void BilateralFilter::bilateralFilterRDOdiamond5x5(PelBuf& resiBuf, const CPelBu int bif_round_add = (BIF_ROUND_ADD) >> (currTU.cs->pps->getBIFStrength()); int bif_round_shift = ( BIF_ROUND_SHIFT ) -(currTU.cs->pps->getBIFStrength()); - const char* LUTrowPtr = getFilterLutParameters( std::min( uiWidth, uiHeight ), currTU.cu->predMode, qp + currTU.cs->pps->getBIFQPOffset(), bfac ); + const char* lutRowPtr = getFilterLutParameters( std::min( uiWidth, uiHeight ), currTU.cu->predMode, qp + currTU.cs->pps->getBIFQPOffset(), bfac ); const unsigned uiPredStride = predBuf.stride; const unsigned uiStrideRes = resiBuf.stride; @@ -778,7 +778,7 @@ void BilateralFilter::bilateralFilterRDOdiamond5x5(PelBuf& resiBuf, const CPelBu std::copy(tempblock + iWidthExtSIMD, tempblock + iWidthExtSIMD + uiWidthExt, tempblock); std::copy(tempblock + iWidthExtSIMD*(uiHeightExt-2), tempblock + iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt, tempblock + iWidthExtSIMD*(uiHeightExt-1)); - m_bilateralFilterDiamond5x5(uiWidth, uiHeight, tempblock, tempblockFiltered, clpRng, piReco, uiRecStride, iWidthExtSIMD, bfac, bif_round_add, bif_round_shift, true, LUTrowPtr ); + m_bilateralFilterDiamond5x5(uiWidth, uiHeight, tempblock, tempblockFiltered, clpRng, piReco, uiRecStride, iWidthExtSIMD, bfac, bif_round_add, bif_round_shift, true, lutRowPtr ); if (!useReco) { @@ -1455,23 +1455,23 @@ void BilateralFilter::bilateralFilterPicRDOperCTU(CodingStructure& cs, PelUnitBu // Note that this test must be done last since it is destroying all // of our filtered data. #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { - for (int y = 0; y < pcv.heightInCtus; y++) + for (int y = 0; y < pcv.heightInCtus; y++) + { + for (int x = 0; x < pcv.widthInCtus; x++) { - for (int x = 0; x < pcv.widthInCtus; x++) - { - UnitArea ctuArea(pcv.chrFormat, Area(x << pcv.maxCUWidthLog2, y << pcv.maxCUHeightLog2, pcv.maxCUWidth, pcv.maxCUWidth)); - ctuArea = clipArea(ctuArea, *cs.slice->getPic()); - PelBuf piRec = rec.subBuf(ctuArea).Y(); - PelBuf piSrc = src.subBuf(ctuArea).Y(); - copyBack(piSrc, piRec); // Copy unfiltered samples back to rec - } + UnitArea ctuArea(pcv.chrFormat, Area(x << pcv.maxCUWidthLog2, y << pcv.maxCUHeightLog2, pcv.maxCUWidth, pcv.maxCUWidth)); + ctuArea = clipArea(ctuArea, *cs.slice->getPic()); + PelBuf piRec = rec.subBuf(ctuArea).Y(); + PelBuf piSrc = src.subBuf(ctuArea).Y(); + copyBack(piSrc, piRec); // Copy unfiltered samples back to rec } + } } else { - rec.copyFrom(src); + rec.copyFrom(src); } #else rec.copyFrom(src); @@ -1490,1033 +1490,996 @@ void BilateralFilter::bilateralFilterPicRDOperCTU(CodingStructure& cs, PelUnitBu #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER -void BilateralFilter::bilateralFilterRDOdiamond5x5_chroma(PelBuf& resiBuf, const CPelBuf& predBuf, PelBuf& recoBuf, int32_t qp, const CPelBuf& recIPredBuf, const ClpRng& clpRng, TransformUnit & currTU, bool useReco, bool isCb) +void BilateralFilter::bilateralFilterRDOdiamond5x5Chroma(PelBuf& resiBuf, const CPelBuf& predBuf, PelBuf& recoBuf, int32_t qp, const CPelBuf& recIPredBuf, const ClpRng& clpRng, TransformUnit & currTU, bool useReco, bool isCb) { - const unsigned uiWidth = predBuf.width; - const unsigned uiHeight = predBuf.height; - - int bfac = 1; - int bif_round_add = (BIF_ROUND_ADD) >> (currTU.cs->pps->getCBIFStrength()); - int bif_round_shift = ( BIF_ROUND_SHIFT ) -(currTU.cs->pps->getCBIFStrength()); + const unsigned uiWidth = predBuf.width; + const unsigned uiHeight = predBuf.height; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - int width_for_strength = currTU.blocks[compID].width; - int height_for_strength = currTU.blocks[compID].height; + int bfac = 1; + int bifRoundAdd = (BIF_ROUND_ADD) >> (currTU.cs->pps->getChromaBIFStrength()); + int bifRoundShift = ( BIF_ROUND_SHIFT ) -(currTU.cs->pps->getChromaBIFStrength()); - if(currTU.blocks[COMPONENT_Y].valid()) - { - width_for_strength = currTU.blocks[COMPONENT_Y].width; - height_for_strength = currTU.blocks[COMPONENT_Y].height; - } + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + int widthForStrength = currTU.blocks[compID].width; + int heightForStrength = currTU.blocks[compID].height; - const char* LUTrowPtr = getFilterLutParameters_chroma( std::min( uiWidth, uiHeight ), currTU.cu->predMode, qp + currTU.cs->pps->getCBIFQPOffset(), bfac, width_for_strength, height_for_strength, currTU.blocks[COMPONENT_Y].valid()); + if(currTU.blocks[COMPONENT_Y].valid()) + { + widthForStrength = currTU.blocks[COMPONENT_Y].width; + heightForStrength = currTU.blocks[COMPONENT_Y].height; + } - const unsigned uiPredStride = predBuf.stride; - const unsigned uiStrideRes = resiBuf.stride; - const unsigned uiRecStride = recoBuf.stride; - const Pel *piPred = predBuf.buf; - Pel *piResi = resiBuf.buf; - Pel *piReco = recoBuf.buf; + const char* lutRowPtr = getFilterLutParametersChroma( std::min( uiWidth, uiHeight ), currTU.cu->predMode, qp + currTU.cs->pps->getChromaBIFQPOffset(), bfac, widthForStrength, heightForStrength, currTU.blocks[COMPONENT_Y].valid()); - const Pel *piPredTemp = piPred; - Pel *piResiTemp = piResi; - Pel *piRecoTemp = piReco; - // Reco = Pred + Resi + const unsigned uiPredStride = predBuf.stride; + const unsigned uiStrideRes = resiBuf.stride; + const unsigned uiRecStride = recoBuf.stride; + const Pel *piPred = predBuf.buf; + Pel *piResi = resiBuf.buf; + Pel *piReco = recoBuf.buf; - Pel *tempBlockPtr; + const Pel *piPredTemp = piPred; + Pel *piResiTemp = piResi; + Pel *piRecoTemp = piReco; + // Reco = Pred + Resi + Pel *tempBlockPtr; - uint32_t uiWidthExt = uiWidth + (NUMBER_PADDED_SAMPLES << 1); - uint32_t uiHeightExt = uiHeight + (NUMBER_PADDED_SAMPLES << 1); + uint32_t uiWidthExt = uiWidth + (NUMBER_PADDED_SAMPLES << 1); + uint32_t uiHeightExt = uiHeight + (NUMBER_PADDED_SAMPLES << 1); - int iWidthExtSIMD = uiWidthExt; - if( uiWidth < 8 ) - { - iWidthExtSIMD = 8 + (NUMBER_PADDED_SAMPLES << 1); - } + int iWidthExtSIMD = uiWidthExt; + if( uiWidth < 8 ) + { + iWidthExtSIMD = 8 + (NUMBER_PADDED_SAMPLES << 1); + } - memset(tempblock, 0, iWidthExtSIMD*uiHeightExt * sizeof(short)); - tempBlockPtr = tempblock + (NUMBER_PADDED_SAMPLES)* iWidthExtSIMD + NUMBER_PADDED_SAMPLES; + memset(tempblock, 0, iWidthExtSIMD*uiHeightExt * sizeof(short)); + tempBlockPtr = tempblock + (NUMBER_PADDED_SAMPLES)* iWidthExtSIMD + NUMBER_PADDED_SAMPLES; - // Clip and move block to temporary block - if (useReco) + // Clip and move block to temporary block + if (useReco) + { + for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) { - for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) - { - std::memcpy(tempBlockPtr, piReco, uiWidth * sizeof(Pel)); - piReco += uiRecStride; - tempBlockPtr += iWidthExtSIMD; - } - piReco = piRecoTemp; + std::memcpy(tempBlockPtr, piReco, uiWidth * sizeof(Pel)); + piReco += uiRecStride; + tempBlockPtr += iWidthExtSIMD; } - else + piReco = piRecoTemp; + } + else + { + for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) { - for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) - { - for (uint32_t uiX = 0; uiX < uiWidth; ++uiX) - { - tempBlockPtr[uiX] = ClipPel(piPred[uiX] + piResi[uiX], clpRng); - } - piPred += uiPredStride; - piResi += uiStrideRes; - piReco += uiRecStride; - tempBlockPtr += iWidthExtSIMD; - } + for (uint32_t uiX = 0; uiX < uiWidth; ++uiX) + { + tempBlockPtr[uiX] = ClipPel(piPred[uiX] + piResi[uiX], clpRng); + } + piPred += uiPredStride; + piResi += uiStrideRes; + piReco += uiRecStride; + tempBlockPtr += iWidthExtSIMD; } + } - piPred = piPredTemp; - piResi = piResiTemp; - piReco = piRecoTemp; + piPred = piPredTemp; + piResi = piResiTemp; + piReco = piRecoTemp; - //USE chroma info to decided - const unsigned uiRecIPredStride = recIPredBuf.stride; - const Pel *piRecIPred = recIPredBuf.buf; + //USE chroma info to decided + const unsigned uiRecIPredStride = recIPredBuf.stride; + const Pel *piRecIPred = recIPredBuf.buf; - for (int yy = 1; yy< uiHeightExt -1 ; yy++) - { - tempblock[yy*iWidthExtSIMD + 1] = tempblock[yy*iWidthExtSIMD + 2]; - tempblock[yy*iWidthExtSIMD + uiWidthExt - 2] = tempblock[yy*iWidthExtSIMD + uiWidthExt - 3]; - } - for (int xx = 1; xx< uiWidthExt - 1; xx++) - { - tempblock[1 * iWidthExtSIMD + xx] = tempblock[2 * iWidthExtSIMD + xx]; - tempblock[(uiHeightExt - 2)*iWidthExtSIMD + xx] = tempblock[(uiHeightExt - 3)*iWidthExtSIMD + xx]; - } + for (int yy = 1; yy< uiHeightExt - 1 ; yy++) + { + tempblock[yy*iWidthExtSIMD + 1] = tempblock[yy*iWidthExtSIMD + 2]; + tempblock[yy*iWidthExtSIMD + uiWidthExt - 2] = tempblock[yy*iWidthExtSIMD + uiWidthExt - 3]; + } + for (int xx = 1; xx< uiWidthExt - 1; xx++) + { + tempblock[1 * iWidthExtSIMD + xx] = tempblock[2 * iWidthExtSIMD + xx]; + tempblock[(uiHeightExt - 2)*iWidthExtSIMD + xx] = tempblock[(uiHeightExt - 3)*iWidthExtSIMD + xx]; + } - bool subTuVer = currTU.chromaPos().x > currTU.cu->chromaPos().x ? true : false; - bool subTuHor = currTU.chromaPos().y > currTU.cu->chromaPos().y ? true : false; + bool subTuVer = currTU.chromaPos().x > currTU.cu->chromaPos().x ? true : false; + bool subTuHor = currTU.chromaPos().y > currTU.cu->chromaPos().y ? true : false; - uint32_t CTUsize_chroma = currTU.cs->slice->getSPS()->getCTUSize() >> 1; + uint32_t chromaScale = getComponentScaleX(compID, currTU.cu->chromaFormat); + int ctuSizeChroma = currTU.cs->slice->getSPS()->getCTUSize() >> chromaScale; + bool isCtuBoundary = currTU.chromaPos().y % ctuSizeChroma == 0; - bool isCTUboundary = currTU.chromaPos().y % CTUsize_chroma == 0; + bool topAvailable = (currTU.chromaPos().y - 2 >= 0) && (currTU.chromaPos().y == currTU.cu->chromaPos().y); - bool topAvailable = (currTU.chromaPos().y - 2 >= 0) && (currTU.chromaPos().y == currTU.cu->chromaPos().y); + topAvailable &= !isCtuBoundary; - topAvailable &= !isCTUboundary; + bool leftAvailable = (currTU.chromaPos().x - 2 >= 0) && (currTU.chromaPos().x == currTU.cu->chromaPos().x); - bool leftAvailable = (currTU.chromaPos().x - 2 >= 0) && (currTU.chromaPos().x == currTU.cu->chromaPos().x); + //if not 420, then don't use rec for padding + if(currTU.cu->chromaFormat != CHROMA_420) + { + subTuHor = false; + subTuVer = false; + leftAvailable = false; + topAvailable = false; + } - //if not 420, then don't use rec for padding - if(currTU.cu->chromaFormat != CHROMA_420){ - subTuHor = false; - subTuVer = false; - leftAvailable = false; - topAvailable = false; + if(topAvailable || leftAvailable || subTuHor || subTuVer) + { + const CompArea &area = isCb ? currTU.blocks[COMPONENT_Cb] : currTU.blocks[COMPONENT_Cr]; + CodingStructure &cs = *currTU.cs; + if (topAvailable && leftAvailable) + { + // top left pixels + tempblock[iWidthExtSIMD + 1] = *(piRecIPred - (uiRecIPredStride)-1); } - - if(topAvailable || leftAvailable || subTuHor || subTuVer) + // top row + if (topAvailable) { - const CompArea &area = isCb ? currTU.blocks[COMPONENT_Cb] : currTU.blocks[COMPONENT_Cr]; - CodingStructure &cs = *currTU.cs; - - if (topAvailable && leftAvailable) - { - // top left pixels - tempblock[iWidthExtSIMD + 1] = *(piRecIPred - (uiRecIPredStride)-1); - } - // top row - if (topAvailable) - { - for (int blockx = 0; blockx < area.width; blockx += 1) - { - // copy 4 pixels one line above block from block to blockx + 3 - std::copy(piRecIPred - (uiRecIPredStride)+blockx, piRecIPred - (uiRecIPredStride)+blockx + 1, tempblock + 2 + iWidthExtSIMD + blockx); - } - } - else if (subTuHor) - { - const CompArea &prevHalfArea = isCb ? currTU.prev->blocks[COMPONENT_Cb] : currTU.prev->blocks[COMPONENT_Cr]; - CPelBuf earlierHalfBuf = cs.getPredBuf(prevHalfArea); - earlierHalfBuf = cs.getRecoBuf(prevHalfArea); - const unsigned earlierStride = earlierHalfBuf.stride; - const Pel *earlierPel = earlierHalfBuf.buf + (currTU.prev->chromaSize().height - 1)*earlierStride; - std::copy(earlierPel, earlierPel + area.width, tempblock + 2 + iWidthExtSIMD); - std::copy(earlierPel - earlierStride, earlierPel - earlierStride + area.width, tempblock + 2); - } - // left column - if (leftAvailable) - { - for (int blocky = 0; blocky < area.height; blocky += 1) - { - tempblock[(iWidthExtSIMD << 1) + (blocky + 0) * iWidthExtSIMD + 1] = *(piRecIPred + (blocky + 0)*uiRecIPredStride - 1); // 1 pel out - } - } - else if (subTuVer) - { - const CompArea &prevHalfArea = isCb ? currTU.prev->blocks[COMPONENT_Cb] : currTU.prev->blocks[COMPONENT_Cr]; - CPelBuf earlierHalfBuf = cs.getPredBuf(prevHalfArea); - earlierHalfBuf = cs.getRecoBuf(prevHalfArea); - const unsigned earlierStride = earlierHalfBuf.stride; - const Pel *earlierPel = earlierHalfBuf.buf + (currTU.prev->chromaSize().width - 1); // second to last pixel of first row of previous block - for (int yy = 0; yy < area.height; yy++) - { - tempblock[(iWidthExtSIMD << 1) + yy * iWidthExtSIMD + 1] = *(earlierPel + yy*earlierStride + 0); - } - } + for (int blockx = 0; blockx < area.width; blockx += 1) + { + // copy 4 pixels one line above block from block to blockx + 3 + std::copy(piRecIPred - (uiRecIPredStride)+blockx, piRecIPred - (uiRecIPredStride)+blockx + 1, tempblock + 2 + iWidthExtSIMD + blockx); + } } - - // Sloppy copying of outer layer - for(int yy = 0; yy < uiHeight+2; yy++) + else if (subTuHor) { - tempblock[iWidthExtSIMD + yy*iWidthExtSIMD] = tempblock[iWidthExtSIMD + yy*iWidthExtSIMD + 1]; - tempblock[iWidthExtSIMD + uiWidthExt - 1 + yy*iWidthExtSIMD] = tempblock[iWidthExtSIMD + uiWidthExt - 2 + yy*iWidthExtSIMD]; + const CompArea &prevHalfArea = isCb ? currTU.prev->blocks[COMPONENT_Cb] : currTU.prev->blocks[COMPONENT_Cr]; + CPelBuf earlierHalfBuf = cs.getPredBuf(prevHalfArea); + earlierHalfBuf = cs.getRecoBuf(prevHalfArea); + const unsigned earlierStride = earlierHalfBuf.stride; + const Pel *earlierPel = earlierHalfBuf.buf + (currTU.prev->chromaSize().height - 1)*earlierStride; + std::copy(earlierPel, earlierPel + area.width, tempblock + 2 + iWidthExtSIMD); + std::copy(earlierPel - earlierStride, earlierPel - earlierStride + area.width, tempblock + 2); } - std::copy(tempblock + iWidthExtSIMD, tempblock + iWidthExtSIMD + uiWidthExt, tempblock); - std::copy(tempblock + iWidthExtSIMD*(uiHeightExt-2), tempblock + iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt, tempblock + iWidthExtSIMD*(uiHeightExt-1)); - - m_bilateralFilterDiamond5x5(uiWidth, uiHeight, tempblock, tempblockFiltered, clpRng, piReco, uiRecStride, iWidthExtSIMD, bfac, bif_round_add, bif_round_shift, true, LUTrowPtr ); - - if (!useReco) + // left column + if (leftAvailable) { - // need to be performed if residual is used - // Resi' = Reco' - Pred - for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) - { - for (uint32_t uiX = 0; uiX < uiWidth; ++uiX) - { - piResi[uiX] = piReco[uiX] - piPred[uiX]; - } - piPred += uiPredStride; - piResi += uiStrideRes; - piReco += uiRecStride; - } + for (int blocky = 0; blocky < area.height; blocky += 1) + { + tempblock[(iWidthExtSIMD << 1) + (blocky + 0) * iWidthExtSIMD + 1] = *(piRecIPred + (blocky + 0)*uiRecIPredStride - 1); // 1 pel out + } } -} + else if (subTuVer) + { + const CompArea &prevHalfArea = isCb ? currTU.prev->blocks[COMPONENT_Cb] : currTU.prev->blocks[COMPONENT_Cr]; + CPelBuf earlierHalfBuf = cs.getPredBuf(prevHalfArea); + earlierHalfBuf = cs.getRecoBuf(prevHalfArea); + const unsigned earlierStride = earlierHalfBuf.stride; + const Pel *earlierPel = earlierHalfBuf.buf + (currTU.prev->chromaSize().width - 1); // second to last pixel of first row of previous block + for (int yy = 0; yy < area.height; yy++) + { + tempblock[(iWidthExtSIMD << 1) + yy * iWidthExtSIMD + 1] = *(earlierPel + yy*earlierStride + 0); + } + } + } + // Sloppy copying of outer layer + for(int yy = 0; yy < uiHeight+2; yy++) + { + tempblock[iWidthExtSIMD + yy*iWidthExtSIMD] = tempblock[iWidthExtSIMD + yy*iWidthExtSIMD + 1]; + tempblock[iWidthExtSIMD + uiWidthExt - 1 + yy*iWidthExtSIMD] = tempblock[iWidthExtSIMD + uiWidthExt - 2 + yy*iWidthExtSIMD]; + } + std::copy(tempblock + iWidthExtSIMD, tempblock + iWidthExtSIMD + uiWidthExt, tempblock); + std::copy(tempblock + iWidthExtSIMD*(uiHeightExt-2), tempblock + iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt, tempblock + iWidthExtSIMD*(uiHeightExt-1)); + m_bilateralFilterDiamond5x5(uiWidth, uiHeight, tempblock, tempblockFiltered, clpRng, piReco, uiRecStride, iWidthExtSIMD, bfac, bifRoundAdd, bifRoundShift, true, lutRowPtr ); + if (!useReco) + { + // need to be performed if residual is used + // Resi' = Reco' - Pred + for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) + { + for (uint32_t uiX = 0; uiX < uiWidth; ++uiX) + { + piResi[uiX] = piReco[uiX] - piPred[uiX]; + } + piPred += uiPredStride; + piResi += uiStrideRes; + piReco += uiRecStride; + } + } +} -void BilateralFilter::bilateralFilterPicRDOperCTU_chroma(CodingStructure& cs, PelUnitBuf& src, CBIFCabacEst* CBifCABACEstimator, bool isCb) +void BilateralFilter::bilateralFilterPicRDOperCTUChroma(CodingStructure& cs, PelUnitBuf& src, ChromaBIFCabacEst* chromaBifCABACEstimator, bool isCb) { + // We must have already copied recobuf into src before running this + // such as src.copyFrom(rec); + const PreCalcValues& pcv = *cs.pcv; - // We must have already copied recobuf into src before running this - // such as src.copyFrom(rec); - const PreCalcValues& pcv = *cs.pcv; - - PelUnitBuf rec = cs.getRecoBuf(); + PelUnitBuf rec = cs.getRecoBuf(); - double frameMSEnoBIF = 0; - double frameMSEallBIF = 0; - double frameMSEswitchBIF = 0; - CBifParams& CBifParams = cs.picture->getCBifParam(); - int ctuIdx = 0; + double frameMseBifOff = 0; + double frameMseBifAllOn = 0; + double frameMseBifSwitch = 0; + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); + int ctuIdx = 0; - for (int y = 0; y < pcv.heightInCtus; y++) + for (int y = 0; y < pcv.heightInCtus; y++) + { + for (int x = 0; x < pcv.widthInCtus; x++) { - for (int x = 0; x < pcv.widthInCtus; x++) - { - UnitArea ctuArea(pcv.chrFormat, Area(x << pcv.maxCUWidthLog2, y << pcv.maxCUHeightLog2, pcv.maxCUWidth, pcv.maxCUWidth)); - - ctuArea = clipArea(ctuArea, *cs.slice->getPic()); - PelBuf piOrg = isCb ? cs.getOrgBuf(ctuArea).Cb() : cs.getOrgBuf(ctuArea).Cr(); - PelBuf piSrc = isCb ? src.subBuf(ctuArea).Cb() : src.subBuf(ctuArea).Cr(); - - double MSEnoBIF = getDist(piSrc, piOrg); - - bool TU_VALID = false; - bool TU_CBF = false; - bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - bool BIF_chroma = false; - - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, ctuArea, CType), CType)) - { - bool chroma_valid = isCb ? currCU.Cb().valid() : currCU.Cr().valid(); - if(!chroma_valid){ - continue; - } - for (auto &currTU : CU::traverseTUs(currCU)) - { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - BIF_chroma = false; - if(!isDualTree) - { - TU_VALID = isCb ? currTU.blocks[COMPONENT_Cb].valid() : currTU.blocks[COMPONENT_Cr].valid(); - TU_CBF = false; - - if(TU_VALID) - { - TU_CBF = (isCb ? TU::getCbf(currTU, COMPONENT_Cb) : TU::getCbf(currTU, COMPONENT_Cr)); - } - BIF_chroma = ((TU_CBF || isInter == false) && (currTU.cu->qp > 17) && (TU_VALID)); - } - else - { - TU_CBF = (isCb ? TU::getCbf(currTU, COMPONENT_Cb) : TU::getCbf(currTU, COMPONENT_Cr)); - BIF_chroma = (TU_CBF || isInter == false) && (currTU.cu->qp > 17); - } - if(BIF_chroma) - { - bilateralFilterDiamond5x5_chroma(src, rec, currTU.cu->qp, isCb ? cs.slice->clpRng(COMPONENT_Cb) : cs.slice->clpRng(COMPONENT_Cr), currTU, isCb); - } - } - } - PelBuf piRec = isCb ? rec.subBuf(ctuArea).Cb() : rec.subBuf(ctuArea).Cr(); - double MSEafterBIF = getDist(piRec, piOrg); - frameMSEnoBIF += MSEnoBIF; - frameMSEallBIF += MSEafterBIF; - if(MSEnoBIF<MSEafterBIF) - { - frameMSEswitchBIF += MSEnoBIF; - if(isCb){ - CBifParams.ctuOn_Cb[ctuIdx] = 0; - } - else{ - CBifParams.ctuOn_Cr[ctuIdx] = 0; - } - } - else - { - frameMSEswitchBIF += MSEafterBIF; - if(isCb){ - CBifParams.ctuOn_Cb[ctuIdx] = 1; - } - else{ - CBifParams.ctuOn_Cr[ctuIdx] = 1; - } - } - ctuIdx++; - } - } + UnitArea ctuArea(pcv.chrFormat, Area(x << pcv.maxCUWidthLog2, y << pcv.maxCUHeightLog2, pcv.maxCUWidth, pcv.maxCUWidth)); + ctuArea = clipArea(ctuArea, *cs.slice->getPic()); + PelBuf piOrg = isCb ? cs.getOrgBuf(ctuArea).Cb() : cs.getOrgBuf(ctuArea).Cr(); + PelBuf piSrc = isCb ? src.subBuf(ctuArea).Cb() : src.subBuf(ctuArea).Cr(); - double lambda = cs.picture->slices[0]->getLambdas()[isCb ? 1 : 2]; - double costAllCTUsBIF = frameMSEallBIF + lambda * 1; // To turn everything on, only slice_bif_all_ctb_enabled_flag = 1, so one bit. - double costNoCTUsBIF = frameMSEnoBIF + lambda * 2; // To turn everything off, slice_bif_all_ctb_enabled = 0 && slice_bif_enabled_flag = 0, so two bits. - double costSwitchCTUsBIF; - // Does CABAC estimation instead + double mseBifOff = getDist(piSrc, piOrg); - const double FracBitsScale = 1.0 / double(1 << SCALE_BITS); - if(isCb) - { - CBifParams.frmOn_Cb = 1; - } - else - { - CBifParams.frmOn_Cr = 1; - } - if(isCb) - { - CBifParams.allCtuOn_Cb = 0; - } - else{ - CBifParams.allCtuOn_Cr = 0; - } - double ctuSwitchBits = isCb ? FracBitsScale*CBifCABACEstimator->getBits_Cb(*cs.slice, CBifParams) : FracBitsScale*CBifCABACEstimator->getBits_Cr(*cs.slice, CBifParams); - costSwitchCTUsBIF = frameMSEswitchBIF + lambda * ctuSwitchBits; + bool tuValid = false; + bool tuCBF = false; + bool isDualTree = CS::isDualITree(cs); + ChannelType chType = isDualTree ? CH_C : CH_L; + bool applyChromaBIF = false; - double bestCost = MAX_DOUBLE; - if (costAllCTUsBIF < bestCost) - { - // If everything should be BIF-filtered, we do not need to change any of the samples, - // since they are already filtered. - bestCost = costAllCTUsBIF; - if(isCb) - { - CBifParams.frmOn_Cb = 1; - } - else - { - CBifParams.frmOn_Cr = 1; - } - if(isCb) - { - CBifParams.allCtuOn_Cb = 1; - } - else{ - CBifParams.allCtuOn_Cr = 1; - } - } - if (costSwitchCTUsBIF < bestCost) - { - bestCost = costSwitchCTUsBIF; - if(isCb) - { - CBifParams.frmOn_Cb = 1; - } - else - { - CBifParams.frmOn_Cr = 1; - } - if(isCb) + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, ctuArea, chType), chType)) + { + bool chromaValid = isCb ? currCU.Cb().valid() : currCU.Cr().valid(); + if(!chromaValid) { - CBifParams.allCtuOn_Cb = 0; - } - else{ - CBifParams.allCtuOn_Cr = 0; + continue; } - // If only some CTUs should be BIF-filtered, we need to restore the ones - // that should not be filtered. This test must be done before the above one - // since it is partly destroying our filtered data. - ctuIdx = 0; - for (int y = 0; y < pcv.heightInCtus; y++) + for (auto &currTU : CU::traverseTUs(currCU)) { - for (int x = 0; x < pcv.widthInCtus; x++) + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + applyChromaBIF = false; + if(!isDualTree) + { + tuValid = isCb ? currTU.blocks[COMPONENT_Cb].valid() : currTU.blocks[COMPONENT_Cr].valid(); + tuCBF = false; + if(tuValid) { - UnitArea ctuArea(pcv.chrFormat, Area(x << pcv.maxCUWidthLog2, y << pcv.maxCUHeightLog2, pcv.maxCUWidth, pcv.maxCUWidth)); - ctuArea = clipArea(ctuArea, *cs.slice->getPic()); - PelBuf piRec = isCb ? rec.subBuf(ctuArea).Cb() : rec.subBuf(ctuArea).Cr(); - PelBuf piSrc = isCb ? src.subBuf(ctuArea).Cb() : src.subBuf(ctuArea).Cr(); - bool isCTUon = isCb ? CBifParams.ctuOn_Cb[ctuIdx] : CBifParams.ctuOn_Cr[ctuIdx]; - if( isCTUon == 0){ - copyBack(piSrc, piRec); // Copy unfiltered samples back to rec - } - ctuIdx++; + tuCBF = (isCb ? TU::getCbf(currTU, COMPONENT_Cb) : TU::getCbf(currTU, COMPONENT_Cr)); } + applyChromaBIF = ((tuCBF || isInter == false) && (currTU.cu->qp > 17) && (tuValid)); + } + else + { + tuCBF = (isCb ? TU::getCbf(currTU, COMPONENT_Cb) : TU::getCbf(currTU, COMPONENT_Cr)); + applyChromaBIF = (tuCBF || isInter == false) && (currTU.cu->qp > 17); + } + if(applyChromaBIF) + { + bilateralFilterDiamond5x5Chroma(src, rec, currTU.cu->qp, isCb ? cs.slice->clpRng(COMPONENT_Cb) : cs.slice->clpRng(COMPONENT_Cr), currTU, isCb); + } } - } - - if (costNoCTUsBIF < bestCost) - { - bestCost = costNoCTUsBIF; + } + PelBuf piRec = isCb ? rec.subBuf(ctuArea).Cb() : rec.subBuf(ctuArea).Cr(); + double mseBifOn = getDist(piRec, piOrg); + frameMseBifOff += mseBifOff; + frameMseBifAllOn += mseBifOn; + if(mseBifOff < mseBifOn) + { + frameMseBifSwitch += mseBifOff; if(isCb) { - CBifParams.frmOn_Cb = 0; + chromaBifParams.ctuOnCb[ctuIdx] = 0; } else { - CBifParams.frmOn_Cr = 0; + chromaBifParams.ctuOnCr[ctuIdx] = 0; } + } + else + { + frameMseBifSwitch += mseBifOn; if(isCb) { - CBifParams.allCtuOn_Cb = 0; + chromaBifParams.ctuOnCb[ctuIdx] = 1; } else { - CBifParams.allCtuOn_Cr = 0; - } - - for (int y = 0; y < pcv.heightInCtus; y++) - { - for (int x = 0; x < pcv.widthInCtus; x++) - { - UnitArea ctuArea(pcv.chrFormat, Area(x << pcv.maxCUWidthLog2, y << pcv.maxCUHeightLog2, pcv.maxCUWidth, pcv.maxCUWidth)); - ctuArea = clipArea(ctuArea, *cs.slice->getPic()); - PelBuf piRec = isCb ? rec.subBuf(ctuArea).Cb() : rec.subBuf(ctuArea).Cr(); - PelBuf piSrc = isCb ? src.subBuf(ctuArea).Cb() : src.subBuf(ctuArea).Cr(); - copyBack(piSrc, piRec); // Copy unfiltered samples back to rec - } + chromaBifParams.ctuOnCr[ctuIdx] = 1; } + } +// for each CTU + ctuIdx++; } + } - if(isCb){ - if (CBifParams.frmOn_Cb == 0) - { - std::fill(CBifParams.ctuOn_Cb.begin(), CBifParams.ctuOn_Cb.end(), 0); - } - else if (CBifParams.allCtuOn_Cb) - { - std::fill(CBifParams.ctuOn_Cb.begin(), CBifParams.ctuOn_Cb.end(), 1); - } - } - else{ - if (CBifParams.frmOn_Cr == 0) - { - std::fill(CBifParams.ctuOn_Cr.begin(), CBifParams.ctuOn_Cr.end(), 0); - } - else if (CBifParams.allCtuOn_Cr) - { - std::fill(CBifParams.ctuOn_Cr.begin(), CBifParams.ctuOn_Cr.end(), 1); - } - } + double lambda = cs.picture->slices[0]->getLambdas()[isCb ? 1 : 2]; + double costAllCTUsBIF = frameMseBifAllOn + lambda * 1; // To turn everything on, only slice_bif_all_ctb_enabled_flag = 1, so one bit. + double costNoCTUsBIF = frameMseBifOff + lambda * 2; // To turn everything off, slice_bif_all_ctb_enabled = 0 && slice_bif_enabled_flag = 0, so two bits. + double costSwitchCTUsBIF; + // Does CABAC estimation instead + const double FracBitsScale = 1.0 / double(1 << SCALE_BITS); + if(isCb) + { + chromaBifParams.frmOnCb = 1; + chromaBifParams.allCtuOnCb = 0; + } + else + { + chromaBifParams.frmOnCr = 1; + chromaBifParams.allCtuOnCr = 0; + } + + double ctuSwitchBits = isCb ? FracBitsScale*chromaBifCABACEstimator->getBitsCb(*cs.slice, chromaBifParams) : FracBitsScale*chromaBifCABACEstimator->getBitsCr(*cs.slice, chromaBifParams); + costSwitchCTUsBIF = frameMseBifSwitch + lambda * ctuSwitchBits; + + double bestCost = MAX_DOUBLE; + if (costAllCTUsBIF < bestCost) + { + // If everything should be BIF-filtered, we do not need to change any of the samples, + // since they are already filtered. + bestCost = costAllCTUsBIF; + if(isCb) + { + chromaBifParams.frmOnCb = 1; + chromaBifParams.allCtuOnCb = 1; + } + else + { + chromaBifParams.frmOnCr = 1; + chromaBifParams.allCtuOnCr = 1; + } + } + if (costSwitchCTUsBIF < bestCost) + { + bestCost = costSwitchCTUsBIF; + if(isCb) + { + chromaBifParams.frmOnCb = 1; + chromaBifParams.allCtuOnCb = 0; + } + else + { + chromaBifParams.frmOnCr = 1; + chromaBifParams.allCtuOnCr = 0; + } + // If only some CTUs should be BIF-filtered, we need to restore the ones + // that should not be filtered. This test must be done before the above one + // since it is partly destroying our filtered data. + ctuIdx = 0; + for (int y = 0; y < pcv.heightInCtus; y++) + { + for (int x = 0; x < pcv.widthInCtus; x++) + { + UnitArea ctuArea(pcv.chrFormat, Area(x << pcv.maxCUWidthLog2, y << pcv.maxCUHeightLog2, pcv.maxCUWidth, pcv.maxCUWidth)); + ctuArea = clipArea(ctuArea, *cs.slice->getPic()); + PelBuf piRec = isCb ? rec.subBuf(ctuArea).Cb() : rec.subBuf(ctuArea).Cr(); + PelBuf piSrc = isCb ? src.subBuf(ctuArea).Cb() : src.subBuf(ctuArea).Cr(); + bool isCTUon = isCb ? chromaBifParams.ctuOnCb[ctuIdx] : chromaBifParams.ctuOnCr[ctuIdx]; + if( isCTUon == false) + { + copyBack(piSrc, piRec); // Copy unfiltered samples back to rec + } + ctuIdx++; + } + } + } + if (costNoCTUsBIF < bestCost) + { + bestCost = costNoCTUsBIF; + if(isCb) + { + chromaBifParams.frmOnCb = 0; + chromaBifParams.allCtuOnCb = 0; + } + else + { + chromaBifParams.frmOnCr = 0; + chromaBifParams.allCtuOnCr = 0; + } + for (int y = 0; y < pcv.heightInCtus; y++) + { + for (int x = 0; x < pcv.widthInCtus; x++) + { + UnitArea ctuArea(pcv.chrFormat, Area(x << pcv.maxCUWidthLog2, y << pcv.maxCUHeightLog2, pcv.maxCUWidth, pcv.maxCUWidth)); + ctuArea = clipArea(ctuArea, *cs.slice->getPic()); + PelBuf piRec = isCb ? rec.subBuf(ctuArea).Cb() : rec.subBuf(ctuArea).Cr(); + PelBuf piSrc = isCb ? src.subBuf(ctuArea).Cb() : src.subBuf(ctuArea).Cr(); + copyBack(piSrc, piRec); // Copy unfiltered samples back to rec + } + } + } + if(isCb) + { + if (chromaBifParams.frmOnCb == 0) + { + std::fill(chromaBifParams.ctuOnCb.begin(), chromaBifParams.ctuOnCb.end(), 0); + } + else if (chromaBifParams.allCtuOnCb) + { + std::fill(chromaBifParams.ctuOnCb.begin(), chromaBifParams.ctuOnCb.end(), 1); + } + } + else + { + if (chromaBifParams.frmOnCr == 0) + { + std::fill(chromaBifParams.ctuOnCr.begin(), chromaBifParams.ctuOnCr.end(), 0); + } + else if (chromaBifParams.allCtuOnCr) + { + std::fill(chromaBifParams.ctuOnCr.begin(), chromaBifParams.ctuOnCr.end(), 1); + } + } } #if JVET_W0066_CCSAO -void BilateralFilter::bilateralFilterDiamond5x5NoClip_chroma(const CPelUnitBuf& src, PelUnitBuf& rec, int32_t qp, const ClpRng& clpRng, TransformUnit & currTU, bool isCb) +void BilateralFilter::bilateralFilterDiamond5x5NoClipChroma(const CPelUnitBuf& src, PelUnitBuf& rec, int32_t qp, const ClpRng& clpRng, TransformUnit & currTU, bool isCb) { + ComponentID compID = isCb ? COMPONENT_Cb :COMPONENT_Cr; + CompArea &compArea = currTU.block(compID); - ComponentID compID = isCb ? COMPONENT_Cb :COMPONENT_Cr; - CompArea &compArea = currTU.block(compID); + const unsigned uiWidth = compArea.width; + const unsigned uiHeight = compArea.height; - const unsigned uiWidth = compArea.width; - const unsigned uiHeight = compArea.height; + int srcStride = src.get(compID).stride; + const Pel *srcPtr = src.get(compID).bufAt(compArea); + const Pel *srcPtrTemp = srcPtr; - int srcStride = src.get(compID).stride; - const Pel *srcPtr = src.get(compID).bufAt(compArea); - const Pel *srcPtrTemp = srcPtr; + int recStride = rec.get(compID).stride; + Pel *recPtr = rec.get(compID).bufAt(compArea); - int recStride = rec.get(compID).stride; - Pel *recPtr = rec.get(compID).bufAt(compArea); + int bfac = 1; + int bifRoundAdd = (BIF_ROUND_ADD) >> (currTU.cs->pps->getChromaBIFStrength()); + int bifRoundShift = (BIF_ROUND_SHIFT) - (currTU.cs->pps->getChromaBIFStrength()); - int bfac = 1; - int bif_round_add = (BIF_ROUND_ADD) >> (currTU.cs->pps->getCBIFStrength()); - int bif_round_shift = (BIF_ROUND_SHIFT) - (currTU.cs->pps->getCBIFStrength()); + int widthForStrength = currTU.blocks[compID].width; + int heightForStrength = currTU.blocks[compID].height; - int width_for_strength = currTU.blocks[compID].width; - int height_for_strength = currTU.blocks[compID].height; + if(currTU.blocks[COMPONENT_Y].valid()) + { + widthForStrength = currTU.blocks[COMPONENT_Y].width; + heightForStrength = currTU.blocks[COMPONENT_Y].height; + } - if(currTU.blocks[COMPONENT_Y].valid()) - { - width_for_strength = currTU.blocks[COMPONENT_Y].width; - height_for_strength = currTU.blocks[COMPONENT_Y].height; - } + const char* lutRowPtr = getFilterLutParametersChroma( std::min( uiWidth, uiHeight ), currTU.cu->predMode, qp + currTU.cs->pps->getChromaBIFQPOffset(), bfac, widthForStrength, heightForStrength, currTU.blocks[COMPONENT_Y].valid()); - const char* LUTrowPtr = getFilterLutParameters_chroma( std::min( uiWidth, uiHeight ), currTU.cu->predMode, qp + currTU.cs->pps->getCBIFQPOffset(), bfac, width_for_strength, height_for_strength, currTU.blocks[COMPONENT_Y].valid()); + uint32_t uiWidthExt = uiWidth + (NUMBER_PADDED_SAMPLES << 1); + uint32_t uiHeightExt = uiHeight + (NUMBER_PADDED_SAMPLES << 1); - uint32_t uiWidthExt = uiWidth + (NUMBER_PADDED_SAMPLES << 1); - uint32_t uiHeightExt = uiHeight + (NUMBER_PADDED_SAMPLES << 1); + int iWidthExtSIMD = uiWidthExt; + if( uiWidth < 8 ) + { + iWidthExtSIMD = 8 + (NUMBER_PADDED_SAMPLES << 1); + } - int iWidthExtSIMD = uiWidthExt; - if( uiWidth < 8 ) - { - iWidthExtSIMD = 8 + (NUMBER_PADDED_SAMPLES << 1); - } + Pel *tempBlockPtr; - Pel *tempBlockPtr; + memset(tempblock, 0, iWidthExtSIMD*uiHeightExt * sizeof(short)); - memset(tempblock, 0, iWidthExtSIMD*uiHeightExt * sizeof(short)); + tempBlockPtr = tempblock + (NUMBER_PADDED_SAMPLES)* iWidthExtSIMD + NUMBER_PADDED_SAMPLES; - tempBlockPtr = tempblock + (NUMBER_PADDED_SAMPLES)* iWidthExtSIMD + NUMBER_PADDED_SAMPLES; + // Move block to temporary block + for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) + { + std::memcpy(tempBlockPtr, srcPtr, uiWidth * sizeof(Pel)); + srcPtr += srcStride; + tempBlockPtr += iWidthExtSIMD; + } + srcPtr = srcPtrTemp; - //// Move block to temporary block - for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) - { - std::memcpy(tempBlockPtr, srcPtr, uiWidth * sizeof(Pel)); - srcPtr += srcStride; - tempBlockPtr += iWidthExtSIMD; - } - srcPtr = srcPtrTemp; + const CompArea &myArea = isCb ? currTU.blocks[COMPONENT_Cb] : currTU.blocks[COMPONENT_Cr]; - const CompArea &myArea = isCb ? currTU.blocks[COMPONENT_Cb] : currTU.blocks[COMPONENT_Cr]; + bool topAltAvailable = myArea.y - NUMBER_PADDED_SAMPLES >= 0; + bool leftAltAvailable = myArea.x - NUMBER_PADDED_SAMPLES >= 0; - bool topAltAvailable = myArea.y - 2 >= 0; - bool leftAltAvailable = myArea.x - 2 >= 0; + int scaleX = getComponentScaleX(compID, currTU.cu->cs->pcv->chrFormat); + int scaleY = getComponentScaleY(compID, currTU.cu->cs->pcv->chrFormat); + uint32_t picWidthChroma = currTU.cu->slice->getPPS()->getPicWidthInLumaSamples() >> scaleX; + uint32_t picHeightChroma = currTU.cu->slice->getPPS()->getPicHeightInLumaSamples() >> scaleY; -// uint32_t chroma_pic_width = currTU.cu->slice->getSPS()->getMaxPicWidthInLumaSamples() >> 1; -// uint32_t chroma_pic_height = currTU.cu->slice->getSPS()->getMaxPicHeightInLumaSamples() >> 1; - int scaleX = getComponentScaleX(compID, currTU.cu->cs->pcv->chrFormat); - int scaleY = getComponentScaleY(compID, currTU.cu->cs->pcv->chrFormat); - uint32_t chroma_pic_width = currTU.cu->slice->getPPS()->getPicWidthInLumaSamples() >> scaleX; - uint32_t chroma_pic_height = currTU.cu->slice->getPPS()->getPicHeightInLumaSamples() >> scaleY; + bool bottomAltAvailable = myArea.y + myArea.height + 1 < picHeightChroma; + bool rightAltAvailable = myArea.x + myArea.width + 1 < picWidthChroma; - bool bottomAltAvailable = myArea.y + myArea.height + 1 < chroma_pic_height; - bool rightAltAvailable = myArea.x + myArea.width + 1 < chroma_pic_width; + bool allAvail = topAltAvailable && bottomAltAvailable && leftAltAvailable && rightAltAvailable; - bool allAvail = topAltAvailable && bottomAltAvailable && leftAltAvailable && rightAltAvailable; + //if not 420, then don't use rec for padding + if(currTU.cu->chromaFormat != CHROMA_420) + { + topAltAvailable = false; + bottomAltAvailable = false; + leftAltAvailable = false; + rightAltAvailable = false; + allAvail = false; + } - //if not 420, then don't use rec for padding - if(currTU.cu->chromaFormat != CHROMA_420) - { - topAltAvailable = false; - bottomAltAvailable = false; - leftAltAvailable = false; - rightAltAvailable = false; - allAvail = false; - } + if(allAvail) + { + // set pointer two rows up and two pixels to the left from the start of the block + tempBlockPtr = tempblock; + // same with image data + srcPtr = srcPtr - 2*srcStride - 2; + // Move block to temporary block + // Check if the block a the top block of a CTU. + int scaleChroma = getComponentScaleX(compID, currTU.cu->chromaFormat); + int ctuSizeChroma = currTU.cs->slice->getSPS()->getCTUSize() >> scaleChroma; + bool isCtuBoundary = myArea.y % ctuSizeChroma == 0; - if(allAvail) + if(isCtuBoundary) { - // set pointer two rows up and two pixels to the left from the start of the block - tempBlockPtr = tempblock; - // same with image data - srcPtr = srcPtr - 2*srcStride - 2; - // Move block to temporary block - // Check if the block a the top block of a CTU. - uint32_t CTUsize_chroma = currTU.cs->slice->getSPS()->getCTUSize() >> 1; - bool isCTUboundary = myArea.y % CTUsize_chroma == 0; - - if(isCTUboundary) - { - // The samples two lines up are out of bounds. (One line above the CTU is OK, since SAO uses that line.) - // Hence the top line of tempblock is unavailable if the block is the top block of a CTU. - // Therefore, copy samples from one line up instead of from two lines up by updating srcPtr *before* copy. - srcPtr += srcStride; - std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); - } - else - { - std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); - srcPtr += srcStride; - } - tempBlockPtr += iWidthExtSIMD; - // Copy samples that are not out of bounds. - for (uint32_t uiY = 1; uiY < uiHeightExt-1; ++uiY) - { - std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); - srcPtr += srcStride; - tempBlockPtr += iWidthExtSIMD; - } - // Check if the block is a bottom block of a CTU. - isCTUboundary = (myArea.y + uiHeight) % CTUsize_chroma == 0; - if(isCTUboundary) - { - // The samples two lines down are out of bounds. (One line below the CTU is OK, since SAO uses that line.) - // Hence the bottom line of tempblock is unavailable if the block at the bottom of a CTU. - // Therefore, copy samples from the second to last line instead of the last line by subtracting srcPtr before copy. - srcPtr -= srcStride; - std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); - } - else - { - std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); - } + // The samples two lines up are out of bounds. (One line above the CTU is OK, since SAO uses that line.) + // Hence the top line of tempblock is unavailable if the block is the top block of a CTU. + // Therefore, copy samples from one line up instead of from two lines up by updating srcPtr *before* copy. + srcPtr += srcStride; + std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); } else { - tempBlockPtr = tempblock + (NUMBER_PADDED_SAMPLES)* iWidthExtSIMD + NUMBER_PADDED_SAMPLES; - // Move block to temporary block - for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) - { - std::memcpy(tempBlockPtr, srcPtr, uiWidth * sizeof(Pel)); - srcPtr += srcStride; - tempBlockPtr += iWidthExtSIMD; - } - srcPtr = srcPtrTemp; - if(topAltAvailable) - { - std::copy(srcPtr - 2*srcStride, srcPtr - 2*srcStride + uiWidth, tempblock + 2); - std::copy(srcPtr - srcStride, srcPtr - srcStride + uiWidth, tempblock + iWidthExtSIMD + 2); - } - if(bottomAltAvailable) - { - std::copy(srcPtr + (uiHeight+1)*srcStride, srcPtr +(uiHeight+1)*srcStride + uiWidth, tempblock + (uiHeightExt-1)*iWidthExtSIMD + 2); - std::copy(srcPtr + uiHeight*srcStride, srcPtr +uiHeight*srcStride + uiWidth, tempblock + (uiHeightExt-2)*iWidthExtSIMD + 2); - } - if(leftAltAvailable) - { - for(int yy = 0; yy<uiHeight; yy++) - { - tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 0] = *(srcPtr + yy*srcStride -2); - tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 1] = *(srcPtr + yy*srcStride -1); - } - } - if(rightAltAvailable) - { - for(int yy = 0; yy<uiHeight; yy++) - { - tempblock[(iWidthExtSIMD<<1) + uiWidthExt-1 + yy*iWidthExtSIMD] = *(srcPtr + uiWidth + yy*srcStride + 1); - tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD] = *(srcPtr + uiWidth + yy*srcStride); - } - } - // if not all available, copy from inside tempbuffer - if(!topAltAvailable) - { - std::copy(tempblock + iWidthExtSIMD*2 + 2, tempblock + iWidthExtSIMD*2 + 2 + uiWidth, tempblock + 2); - std::copy(tempblock + iWidthExtSIMD*2 + 2, tempblock + iWidthExtSIMD*2 + 2 + uiWidth, tempblock + iWidthExtSIMD + 2); - } - if(!bottomAltAvailable) - { - std::copy(tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2, tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2 + uiWidth, tempblock + (uiHeightExt-2)*iWidthExtSIMD + 2); - std::copy(tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2, tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2 + uiWidth, tempblock + (uiHeightExt-1)*iWidthExtSIMD + 2); - } - if(!leftAltAvailable) - { - for(int yy = 0; yy<uiHeight; yy++) - { - tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 0] = tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 2]; - tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 1] = tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 2]; - } - } - if(!rightAltAvailable) - { - for(int yy = 0; yy<uiHeight; yy++) - { - tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD] = tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD - 1]; - tempblock[(iWidthExtSIMD<<1) + uiWidthExt-1 + yy*iWidthExtSIMD] = tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD - 1]; - } - } - // All sides are available, easy to just copy corners also. - if(topAltAvailable && leftAltAvailable) - { - tempblock[0] = *(srcPtr - 2*srcStride -2); // a top left corner - tempblock[1] = *(srcPtr - 2*srcStride -1); // b a b|x x - tempblock[iWidthExtSIMD + 0] = *(srcPtr - srcStride -2); // c c d|x x - tempblock[iWidthExtSIMD + 1] = *(srcPtr - srcStride -1); // d ------- - } - else - { - tempblock[0] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left - tempblock[1] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left - tempblock[iWidthExtSIMD + 0] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left - tempblock[iWidthExtSIMD + 1] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left - } - if(topAltAvailable && rightAltAvailable) - { - tempblock[iWidthExtSIMD - 2] = *(srcPtr - 2*srcStride + uiWidth); // a - tempblock[iWidthExtSIMD - 1] = *(srcPtr - 2*srcStride + uiWidth + 1); // b - tempblock[iWidthExtSIMD + uiWidthExt - 2] = *(srcPtr - srcStride + uiWidth); // c - tempblock[iWidthExtSIMD + uiWidthExt - 1] = *(srcPtr - srcStride + uiWidth + 1); // d - } - else - { - tempblock[iWidthExtSIMD - 2] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right - tempblock[iWidthExtSIMD - 1] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right - tempblock[iWidthExtSIMD + uiWidthExt - 2] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right - tempblock[iWidthExtSIMD + uiWidthExt - 1] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right - } - if(bottomAltAvailable && leftAltAvailable) - { - tempblock[iWidthExtSIMD*(uiHeightExt-2) + 0] = *(srcPtr + uiHeight*srcStride -2); // a - tempblock[iWidthExtSIMD*(uiHeightExt-2) + 1] = *(srcPtr + uiHeight*srcStride -1); // b - tempblock[iWidthExtSIMD*(uiHeightExt-1) + 0] = *(srcPtr + (uiHeight+1)*srcStride -2); // c - tempblock[iWidthExtSIMD*(uiHeightExt-1) + 1] = *(srcPtr + (uiHeight+1)*srcStride -1); // d - } - else - { - tempblock[iWidthExtSIMD*(uiHeightExt-2) + 0] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right - tempblock[iWidthExtSIMD*(uiHeightExt-2) + 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right - tempblock[iWidthExtSIMD*(uiHeightExt-1) + 0] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right - tempblock[iWidthExtSIMD*(uiHeightExt-1) + 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right - } - if(bottomAltAvailable && rightAltAvailable) - { - tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 2] = *(srcPtr + uiHeight*srcStride + uiWidth); // a - tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 1] = *(srcPtr + uiHeight*srcStride + uiWidth + 1); // b - tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 2] = *(srcPtr + (uiHeight+1)*srcStride + uiWidth); // c - tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 1] = *(srcPtr + (uiHeight+1)*srcStride + uiWidth + 1); // d - } - else - { - tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 2] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; - tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; - tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 2] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; - tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; - } + std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); + srcPtr += srcStride; } - - m_bilateralFilterDiamond5x5NoClip(uiWidth, uiHeight, tempblock, tempblockFiltered, clpRng, recPtr, recStride, iWidthExtSIMD, bfac, bif_round_add, bif_round_shift, false, LUTrowPtr ); -} -#endif //BIFchroma no clip - -void BilateralFilter::bilateralFilterDiamond5x5_chroma(const CPelUnitBuf& src, PelUnitBuf& rec, int32_t qp, const ClpRng& clpRng, TransformUnit & currTU, bool isCb) -{ - - ComponentID compID = isCb ? COMPONENT_Cb :COMPONENT_Cr; - CompArea &compArea = currTU.block(compID); - - const unsigned uiWidth = compArea.width; - const unsigned uiHeight = compArea.height; - - int srcStride = src.get(compID).stride; - const Pel *srcPtr = src.get(compID).bufAt(compArea); - const Pel *srcPtrTemp = srcPtr; - - int recStride = rec.get(compID).stride; - Pel *recPtr = rec.get(compID).bufAt(compArea); - - int bfac = 1; - int bif_round_add = (BIF_ROUND_ADD) >> (currTU.cs->pps->getCBIFStrength()); - int bif_round_shift = (BIF_ROUND_SHIFT) - (currTU.cs->pps->getCBIFStrength()); - - int width_for_strength = currTU.blocks[compID].width; - int height_for_strength = currTU.blocks[compID].height; - - if(currTU.blocks[COMPONENT_Y].valid()) + tempBlockPtr += iWidthExtSIMD; + // Copy samples that are not out of bounds. + for (uint32_t uiY = 1; uiY < uiHeightExt-1; ++uiY) { - width_for_strength = currTU.blocks[COMPONENT_Y].width; - height_for_strength = currTU.blocks[COMPONENT_Y].height; + std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); + srcPtr += srcStride; + tempBlockPtr += iWidthExtSIMD; } - - const char* LUTrowPtr = getFilterLutParameters_chroma( std::min( uiWidth, uiHeight ), currTU.cu->predMode, qp + currTU.cs->pps->getCBIFQPOffset(), bfac, width_for_strength, height_for_strength, currTU.blocks[COMPONENT_Y].valid()); - - uint32_t uiWidthExt = uiWidth + (NUMBER_PADDED_SAMPLES << 1); - uint32_t uiHeightExt = uiHeight + (NUMBER_PADDED_SAMPLES << 1); - - int iWidthExtSIMD = uiWidthExt; - if( uiWidth < 8 ) + // Check if the block is a bottom block of a CTU. + isCtuBoundary = (myArea.y + uiHeight) % ctuSizeChroma == 0; + if(isCtuBoundary) { - iWidthExtSIMD = 8 + (NUMBER_PADDED_SAMPLES << 1); + // The samples two lines down are out of bounds. (One line below the CTU is OK, since SAO uses that line.) + // Hence the bottom line of tempblock is unavailable if the block at the bottom of a CTU. + // Therefore, copy samples from the second to last line instead of the last line by subtracting srcPtr before copy. + srcPtr -= srcStride; + std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); } - - Pel *tempBlockPtr; - - memset(tempblock, 0, iWidthExtSIMD*uiHeightExt * sizeof(short)); - + else + { + std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); + } + } + else + { tempBlockPtr = tempblock + (NUMBER_PADDED_SAMPLES)* iWidthExtSIMD + NUMBER_PADDED_SAMPLES; - // Move block to temporary block for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) { - std::memcpy(tempBlockPtr, srcPtr, uiWidth * sizeof(Pel)); - srcPtr += srcStride; - tempBlockPtr += iWidthExtSIMD; + std::memcpy(tempBlockPtr, srcPtr, uiWidth * sizeof(Pel)); + srcPtr += srcStride; + tempBlockPtr += iWidthExtSIMD; } srcPtr = srcPtrTemp; - const CompArea &myArea = isCb ? currTU.blocks[COMPONENT_Cb] : currTU.blocks[COMPONENT_Cr]; - bool topAltAvailable = myArea.y - 2 >= 0; - bool leftAltAvailable = myArea.x - 2 >= 0; - -// uint32_t chroma_pic_width = currTU.cu->slice->getSPS()->getMaxPicWidthInLumaSamples() >> 1; -// uint32_t chroma_pic_height = currTU.cu->slice->getSPS()->getMaxPicHeightInLumaSamples() >> 1; - int scaleX = getComponentScaleX(compID, currTU.cu->cs->pcv->chrFormat); - int scaleY = getComponentScaleY(compID, currTU.cu->cs->pcv->chrFormat); - uint32_t chroma_pic_width = currTU.cu->slice->getPPS()->getPicWidthInLumaSamples() >> scaleX; - uint32_t chroma_pic_height = currTU.cu->slice->getPPS()->getPicHeightInLumaSamples() >> scaleY; - - bool bottomAltAvailable = myArea.y + myArea.height + 1 < chroma_pic_height; - bool rightAltAvailable = myArea.x + myArea.width + 1 < chroma_pic_width; - - bool allAvail = topAltAvailable && bottomAltAvailable && leftAltAvailable && rightAltAvailable; - - //if not 420, then don't use rec for padding - if(currTU.cu->chromaFormat != CHROMA_420){ - topAltAvailable = false; - bottomAltAvailable = false; - leftAltAvailable = false; - rightAltAvailable = false; - allAvail = false; - } - if(allAvail) - { - // set pointer two rows up and two pixels to the left from the start of the block - tempBlockPtr = tempblock; - // same with image data - srcPtr = srcPtr - 2*srcStride - 2; - // Move block to temporary block - // Check if the block a the top block of a CTU. - uint32_t CTUsize_chroma = currTU.cs->slice->getSPS()->getCTUSize() >> 1; - bool isCTUboundary = myArea.y % CTUsize_chroma == 0; - - if(isCTUboundary) - { - // The samples two lines up are out of bounds. (One line above the CTU is OK, since SAO uses that line.) - // Hence the top line of tempblock is unavailable if the block is the top block of a CTU. - // Therefore, copy samples from one line up instead of from two lines up by updating srcPtr *before* copy. - srcPtr += srcStride; - std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); - } - else - { - std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); - srcPtr += srcStride; - } - tempBlockPtr += iWidthExtSIMD; - // Copy samples that are not out of bounds. - for (uint32_t uiY = 1; uiY < uiHeightExt-1; ++uiY) - { - std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); - srcPtr += srcStride; - tempBlockPtr += iWidthExtSIMD; - } - // Check if the block is a bottom block of a CTU. - isCTUboundary = (myArea.y + uiHeight) % CTUsize_chroma == 0; - if(isCTUboundary) - { - // The samples two lines down are out of bounds. (One line below the CTU is OK, since SAO uses that line.) - // Hence the bottom line of tempblock is unavailable if the block at the bottom of a CTU. - // Therefore, copy samples from the second to last line instead of the last line by subtracting srcPtr before copy. - srcPtr -= srcStride; - std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); - } - else - { - std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); - } + if(topAltAvailable) + { + std::copy(srcPtr - 2*srcStride, srcPtr - 2*srcStride + uiWidth, tempblock + 2); + std::copy(srcPtr - srcStride, srcPtr - srcStride + uiWidth, tempblock + iWidthExtSIMD + 2); } - else + if(bottomAltAvailable) { - tempBlockPtr = tempblock + (NUMBER_PADDED_SAMPLES)* iWidthExtSIMD + NUMBER_PADDED_SAMPLES; - // Move block to temporary block - for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) - { - std::memcpy(tempBlockPtr, srcPtr, uiWidth * sizeof(Pel)); - srcPtr += srcStride; - tempBlockPtr += iWidthExtSIMD; - } - srcPtr = srcPtrTemp; - if(topAltAvailable) - { - std::copy(srcPtr - 2*srcStride, srcPtr - 2*srcStride + uiWidth, tempblock + 2); - std::copy(srcPtr - srcStride, srcPtr - srcStride + uiWidth, tempblock + iWidthExtSIMD + 2); - } - if(bottomAltAvailable) - { - std::copy(srcPtr + (uiHeight+1)*srcStride, srcPtr +(uiHeight+1)*srcStride + uiWidth, tempblock + (uiHeightExt-1)*iWidthExtSIMD + 2); - std::copy(srcPtr + uiHeight*srcStride, srcPtr +uiHeight*srcStride + uiWidth, tempblock + (uiHeightExt-2)*iWidthExtSIMD + 2); - } - if(leftAltAvailable) - { - for(int yy = 0; yy<uiHeight; yy++) - { - tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 0] = *(srcPtr + yy*srcStride -2); - tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 1] = *(srcPtr + yy*srcStride -1); - } - } - if(rightAltAvailable) - { - for(int yy = 0; yy<uiHeight; yy++) - { - tempblock[(iWidthExtSIMD<<1) + uiWidthExt-1 + yy*iWidthExtSIMD] = *(srcPtr + uiWidth + yy*srcStride + 1); - tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD] = *(srcPtr + uiWidth + yy*srcStride); - } - } - // if not all available, copy from inside tempbuffer - if(!topAltAvailable) - { - std::copy(tempblock + iWidthExtSIMD*2 + 2, tempblock + iWidthExtSIMD*2 + 2 + uiWidth, tempblock + 2); - std::copy(tempblock + iWidthExtSIMD*2 + 2, tempblock + iWidthExtSIMD*2 + 2 + uiWidth, tempblock + iWidthExtSIMD + 2); - } - if(!bottomAltAvailable) - { - std::copy(tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2, tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2 + uiWidth, tempblock + (uiHeightExt-2)*iWidthExtSIMD + 2); - std::copy(tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2, tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2 + uiWidth, tempblock + (uiHeightExt-1)*iWidthExtSIMD + 2); - } - if(!leftAltAvailable) - { - for(int yy = 0; yy<uiHeight; yy++) - { - tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 0] = tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 2]; - tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 1] = tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 2]; - } - } - if(!rightAltAvailable) - { - for(int yy = 0; yy<uiHeight; yy++) - { - tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD] = tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD - 1]; - tempblock[(iWidthExtSIMD<<1) + uiWidthExt-1 + yy*iWidthExtSIMD] = tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD - 1]; - } - } - // All sides are available, easy to just copy corners also. - if(topAltAvailable && leftAltAvailable) - { - tempblock[0] = *(srcPtr - 2*srcStride -2); // a top left corner - tempblock[1] = *(srcPtr - 2*srcStride -1); // b a b|x x - tempblock[iWidthExtSIMD + 0] = *(srcPtr - srcStride -2); // c c d|x x - tempblock[iWidthExtSIMD + 1] = *(srcPtr - srcStride -1); // d ------- - } - else - { - tempblock[0] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left - tempblock[1] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left - tempblock[iWidthExtSIMD + 0] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left - tempblock[iWidthExtSIMD + 1] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left - } - if(topAltAvailable && rightAltAvailable) - { - tempblock[iWidthExtSIMD - 2] = *(srcPtr - 2*srcStride + uiWidth); // a - tempblock[iWidthExtSIMD - 1] = *(srcPtr - 2*srcStride + uiWidth + 1); // b - tempblock[iWidthExtSIMD + uiWidthExt - 2] = *(srcPtr - srcStride + uiWidth); // c - tempblock[iWidthExtSIMD + uiWidthExt - 1] = *(srcPtr - srcStride + uiWidth + 1); // d - } - else - { - tempblock[iWidthExtSIMD - 2] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right - tempblock[iWidthExtSIMD - 1] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right - tempblock[iWidthExtSIMD + uiWidthExt - 2] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right - tempblock[iWidthExtSIMD + uiWidthExt - 1] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right - } - if(bottomAltAvailable && leftAltAvailable) - { - tempblock[iWidthExtSIMD*(uiHeightExt-2) + 0] = *(srcPtr + uiHeight*srcStride -2); // a - tempblock[iWidthExtSIMD*(uiHeightExt-2) + 1] = *(srcPtr + uiHeight*srcStride -1); // b - tempblock[iWidthExtSIMD*(uiHeightExt-1) + 0] = *(srcPtr + (uiHeight+1)*srcStride -2); // c - tempblock[iWidthExtSIMD*(uiHeightExt-1) + 1] = *(srcPtr + (uiHeight+1)*srcStride -1); // d - } - else - { - tempblock[iWidthExtSIMD*(uiHeightExt-2) + 0] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right - tempblock[iWidthExtSIMD*(uiHeightExt-2) + 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right - tempblock[iWidthExtSIMD*(uiHeightExt-1) + 0] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right - tempblock[iWidthExtSIMD*(uiHeightExt-1) + 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right - } - if(bottomAltAvailable && rightAltAvailable) - { - tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 2] = *(srcPtr + uiHeight*srcStride + uiWidth); // a - tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 1] = *(srcPtr + uiHeight*srcStride + uiWidth + 1); // b - tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 2] = *(srcPtr + (uiHeight+1)*srcStride + uiWidth); // c - tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 1] = *(srcPtr + (uiHeight+1)*srcStride + uiWidth + 1); // d - } - else - { - tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 2] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; - tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; - tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 2] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; - tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; - } + std::copy(srcPtr + (uiHeight+1)*srcStride, srcPtr +(uiHeight+1)*srcStride + uiWidth, tempblock + (uiHeightExt-1)*iWidthExtSIMD + 2); + std::copy(srcPtr + uiHeight*srcStride, srcPtr +uiHeight*srcStride + uiWidth, tempblock + (uiHeightExt-2)*iWidthExtSIMD + 2); } - - m_bilateralFilterDiamond5x5(uiWidth, uiHeight, tempblock, tempblockFiltered, clpRng, recPtr, recStride, iWidthExtSIMD, bfac, bif_round_add, bif_round_shift, false, LUTrowPtr ); + if(leftAltAvailable) + { + for(int yy = 0; yy<uiHeight; yy++) + { + tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 0] = *(srcPtr + yy*srcStride -2); + tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 1] = *(srcPtr + yy*srcStride -1); + } + } + if(rightAltAvailable) + { + for(int yy = 0; yy<uiHeight; yy++) + { + tempblock[(iWidthExtSIMD<<1) + uiWidthExt-1 + yy*iWidthExtSIMD] = *(srcPtr + uiWidth + yy*srcStride + 1); + tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD] = *(srcPtr + uiWidth + yy*srcStride); + } + } + // if not all available, copy from inside tempbuffer + if(!topAltAvailable) + { + std::copy(tempblock + iWidthExtSIMD*2 + 2, tempblock + iWidthExtSIMD*2 + 2 + uiWidth, tempblock + 2); + std::copy(tempblock + iWidthExtSIMD*2 + 2, tempblock + iWidthExtSIMD*2 + 2 + uiWidth, tempblock + iWidthExtSIMD + 2); + } + if(!bottomAltAvailable) + { + std::copy(tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2, tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2 + uiWidth, tempblock + (uiHeightExt-2)*iWidthExtSIMD + 2); + std::copy(tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2, tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2 + uiWidth, tempblock + (uiHeightExt-1)*iWidthExtSIMD + 2); + } + if(!leftAltAvailable) + { + for(int yy = 0; yy<uiHeight; yy++) + { + tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 0] = tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 2]; + tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 1] = tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 2]; + } + } + if(!rightAltAvailable) + { + for(int yy = 0; yy<uiHeight; yy++) + { + tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD] = tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD - 1]; + tempblock[(iWidthExtSIMD<<1) + uiWidthExt-1 + yy*iWidthExtSIMD] = tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD - 1]; + } + } + // All sides are available, easy to just copy corners also. + if(topAltAvailable && leftAltAvailable) + { + tempblock[0] = *(srcPtr - 2*srcStride -2); // a top left corner + tempblock[1] = *(srcPtr - 2*srcStride -1); // b a b|x x + tempblock[iWidthExtSIMD + 0] = *(srcPtr - srcStride -2); // c c d|x x + tempblock[iWidthExtSIMD + 1] = *(srcPtr - srcStride -1); // d ------- + } + else + { + tempblock[0] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left + tempblock[1] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left + tempblock[iWidthExtSIMD + 0] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left + tempblock[iWidthExtSIMD + 1] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left + } + if(topAltAvailable && rightAltAvailable) + { + tempblock[iWidthExtSIMD - 2] = *(srcPtr - 2*srcStride + uiWidth); // a + tempblock[iWidthExtSIMD - 1] = *(srcPtr - 2*srcStride + uiWidth + 1); // b + tempblock[iWidthExtSIMD + uiWidthExt - 2] = *(srcPtr - srcStride + uiWidth); // c + tempblock[iWidthExtSIMD + uiWidthExt - 1] = *(srcPtr - srcStride + uiWidth + 1); // d + } + else + { + tempblock[iWidthExtSIMD - 2] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right + tempblock[iWidthExtSIMD - 1] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right + tempblock[iWidthExtSIMD + uiWidthExt - 2] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right + tempblock[iWidthExtSIMD + uiWidthExt - 1] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right + } + if(bottomAltAvailable && leftAltAvailable) + { + tempblock[iWidthExtSIMD*(uiHeightExt-2) + 0] = *(srcPtr + uiHeight*srcStride -2); // a + tempblock[iWidthExtSIMD*(uiHeightExt-2) + 1] = *(srcPtr + uiHeight*srcStride -1); // b + tempblock[iWidthExtSIMD*(uiHeightExt-1) + 0] = *(srcPtr + (uiHeight+1)*srcStride -2); // c + tempblock[iWidthExtSIMD*(uiHeightExt-1) + 1] = *(srcPtr + (uiHeight+1)*srcStride -1); // d + } + else + { + tempblock[iWidthExtSIMD*(uiHeightExt-2) + 0] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right + tempblock[iWidthExtSIMD*(uiHeightExt-2) + 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right + tempblock[iWidthExtSIMD*(uiHeightExt-1) + 0] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right + tempblock[iWidthExtSIMD*(uiHeightExt-1) + 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right + } + if(bottomAltAvailable && rightAltAvailable) + { + tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 2] = *(srcPtr + uiHeight*srcStride + uiWidth); // a + tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 1] = *(srcPtr + uiHeight*srcStride + uiWidth + 1); // b + tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 2] = *(srcPtr + (uiHeight+1)*srcStride + uiWidth); // c + tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 1] = *(srcPtr + (uiHeight+1)*srcStride + uiWidth + 1); // d + } + else + { + tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 2] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; + tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; + tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 2] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; + tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; + } + } + m_bilateralFilterDiamond5x5NoClip(uiWidth, uiHeight, tempblock, tempblockFiltered, clpRng, recPtr, recStride, iWidthExtSIMD, bfac, bifRoundAdd, bifRoundShift, false, lutRowPtr ); } +#endif //chromaBIF no clip -void BilateralFilter::clipNotBilaterallyFilteredBlocks_chroma(const CPelUnitBuf& src, PelUnitBuf& rec, const ClpRng& clpRng, TransformUnit & currTU, bool isCb) +void BilateralFilter::bilateralFilterDiamond5x5Chroma(const CPelUnitBuf& src, PelUnitBuf& rec, int32_t qp, const ClpRng& clpRng, TransformUnit & currTU, bool isCb) { - PelUnitBuf myRecBuf = currTU.cs->getRecoBuf(currTU); - int cid = isCb ? COMPONENT_Cb : COMPONENT_Cr; - if(myRecBuf.bufs[cid].width > 1) + ComponentID compID = isCb ? COMPONENT_Cb :COMPONENT_Cr; + CompArea &compArea = currTU.block(compID); + + const unsigned uiWidth = compArea.width; + const unsigned uiHeight = compArea.height; + + int srcStride = src.get(compID).stride; + const Pel *srcPtr = src.get(compID).bufAt(compArea); + const Pel *srcPtrTemp = srcPtr; + + int recStride = rec.get(compID).stride; + Pel *recPtr = rec.get(compID).bufAt(compArea); + + int bfac = 1; + int bifRoundAdd = (BIF_ROUND_ADD) >> (currTU.cs->pps->getChromaBIFStrength()); + int bifRoundShift = (BIF_ROUND_SHIFT) - (currTU.cs->pps->getChromaBIFStrength()); + + int widthForStrength = currTU.blocks[compID].width; + int heightForStrength = currTU.blocks[compID].height; + + if(currTU.blocks[COMPONENT_Y].valid()) + { + widthForStrength = currTU.blocks[COMPONENT_Y].width; + heightForStrength = currTU.blocks[COMPONENT_Y].height; + } + + const char* lutRowPtr = getFilterLutParametersChroma( std::min( uiWidth, uiHeight ), currTU.cu->predMode, qp + currTU.cs->pps->getChromaBIFQPOffset(), bfac, widthForStrength, heightForStrength, currTU.blocks[COMPONENT_Y].valid()); + + uint32_t uiWidthExt = uiWidth + (NUMBER_PADDED_SAMPLES << 1); + uint32_t uiHeightExt = uiHeight + (NUMBER_PADDED_SAMPLES << 1); + + int iWidthExtSIMD = uiWidthExt; + if( uiWidth < 8 ) + { + iWidthExtSIMD = 8 + (NUMBER_PADDED_SAMPLES << 1); + } + + Pel *tempBlockPtr; + + memset(tempblock, 0, iWidthExtSIMD*uiHeightExt * sizeof(short)); + + tempBlockPtr = tempblock + (NUMBER_PADDED_SAMPLES)* iWidthExtSIMD + NUMBER_PADDED_SAMPLES; + + // Move block to temporary block + for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) + { + std::memcpy(tempBlockPtr, srcPtr, uiWidth * sizeof(Pel)); + srcPtr += srcStride; + tempBlockPtr += iWidthExtSIMD; + } + srcPtr = srcPtrTemp; + const CompArea &myArea = isCb ? currTU.blocks[COMPONENT_Cb] : currTU.blocks[COMPONENT_Cr]; + bool topAltAvailable = myArea.y - NUMBER_PADDED_SAMPLES >= 0; + bool leftAltAvailable = myArea.x - NUMBER_PADDED_SAMPLES >= 0; + + int scaleX = getComponentScaleX(compID, currTU.cu->cs->pcv->chrFormat); + int scaleY = getComponentScaleY(compID, currTU.cu->cs->pcv->chrFormat); + int picWidthChroma = currTU.cu->slice->getPPS()->getPicWidthInLumaSamples() >> scaleX; + int picHeightChroma = currTU.cu->slice->getPPS()->getPicHeightInLumaSamples() >> scaleY; + + bool bottomAltAvailable = myArea.y + myArea.height + 1 < picHeightChroma; + bool rightAltAvailable = myArea.x + myArea.width + 1 < picWidthChroma; + + bool allAvail = topAltAvailable && bottomAltAvailable && leftAltAvailable && rightAltAvailable; + + //if not 420, then don't use rec for padding + if(currTU.cu->chromaFormat != CHROMA_420) + { + topAltAvailable = false; + bottomAltAvailable = false; + leftAltAvailable = false; + rightAltAvailable = false; + allAvail = false; + } + if(allAvail) + { + // set pointer two rows up and two pixels to the left from the start of the block + tempBlockPtr = tempblock; + // same with image data + srcPtr = srcPtr - 2*srcStride - 2; + // Move block to temporary block + // Check if the block a the top block of a CTU. + int scaleChroma = getComponentScaleX(compID, currTU.cu->chromaFormat); + int ctuSizeChroma = currTU.cs->slice->getSPS()->getCTUSize() >> scaleChroma; + bool isCtuBoundary = myArea.y % ctuSizeChroma == 0; + + if(isCtuBoundary) { - // new result = old result (which is SAO-treated already) + diff due to bilateral filtering - myRecBuf.bufs[cid].copyClip(myRecBuf.bufs[cid], clpRng); + // The samples two lines up are out of bounds. (One line above the CTU is OK, since SAO uses that line.) + // Hence the top line of tempblock is unavailable if the block is the top block of a CTU. + // Therefore, copy samples from one line up instead of from two lines up by updating srcPtr *before* copy. + srcPtr += srcStride; + std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); } else { - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - CompArea &compArea = currTU.block(compID); - const unsigned uiHeight = compArea.height; - int recStride = rec.get(compID).stride; - Pel *recPtr = rec.get(compID).bufAt(compArea); - - for(uint32_t yy = 0; yy < uiHeight; yy++){ - // new result = old result (which is SAO-treated already) + diff due to bilateral filtering - recPtr[0] = ClipPel<int>(recPtr[0], clpRng); - recPtr += recStride; - } + std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); + srcPtr += srcStride; + } + tempBlockPtr += iWidthExtSIMD; + // Copy samples that are not out of bounds. + for (uint32_t uiY = 1; uiY < uiHeightExt-1; ++uiY) + { + std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); + srcPtr += srcStride; + tempBlockPtr += iWidthExtSIMD; + } + // Check if the block is a bottom block of a CTU. + isCtuBoundary = (myArea.y + uiHeight) % ctuSizeChroma == 0; + if(isCtuBoundary) + { + // The samples two lines down are out of bounds. (One line below the CTU is OK, since SAO uses that line.) + // Hence the bottom line of tempblock is unavailable if the block at the bottom of a CTU. + // Therefore, copy samples from the second to last line instead of the last line by subtracting srcPtr before copy. + srcPtr -= srcStride; + std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); + } + else + { + std::memcpy(tempBlockPtr, srcPtr, (uiWidthExt) * sizeof(Pel)); + } + } + else + { + tempBlockPtr = tempblock + (NUMBER_PADDED_SAMPLES)* iWidthExtSIMD + NUMBER_PADDED_SAMPLES; + // Move block to temporary block + for (uint32_t uiY = 0; uiY < uiHeight; ++uiY) + { + std::memcpy(tempBlockPtr, srcPtr, uiWidth * sizeof(Pel)); + srcPtr += srcStride; + tempBlockPtr += iWidthExtSIMD; + } + srcPtr = srcPtrTemp; + if(topAltAvailable) + { + std::copy(srcPtr - 2*srcStride, srcPtr - 2*srcStride + uiWidth, tempblock + 2); + std::copy(srcPtr - srcStride, srcPtr - srcStride + uiWidth, tempblock + iWidthExtSIMD + 2); + } + if(bottomAltAvailable) + { + std::copy(srcPtr + (uiHeight+1)*srcStride, srcPtr +(uiHeight+1)*srcStride + uiWidth, tempblock + (uiHeightExt-1)*iWidthExtSIMD + 2); + std::copy(srcPtr + uiHeight*srcStride, srcPtr +uiHeight*srcStride + uiWidth, tempblock + (uiHeightExt-2)*iWidthExtSIMD + 2); + } + if(leftAltAvailable) + { + for(int yy = 0; yy<uiHeight; yy++) + { + tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 0] = *(srcPtr + yy*srcStride -2); + tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 1] = *(srcPtr + yy*srcStride -1); + } + } + if(rightAltAvailable) + { + for(int yy = 0; yy<uiHeight; yy++) + { + tempblock[(iWidthExtSIMD<<1) + uiWidthExt-1 + yy*iWidthExtSIMD] = *(srcPtr + uiWidth + yy*srcStride + 1); + tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD] = *(srcPtr + uiWidth + yy*srcStride); + } + } + // if not all available, copy from inside tempbuffer + if(!topAltAvailable) + { + std::copy(tempblock + iWidthExtSIMD*2 + 2, tempblock + iWidthExtSIMD*2 + 2 + uiWidth, tempblock + 2); + std::copy(tempblock + iWidthExtSIMD*2 + 2, tempblock + iWidthExtSIMD*2 + 2 + uiWidth, tempblock + iWidthExtSIMD + 2); + } + if(!bottomAltAvailable) + { + std::copy(tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2, tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2 + uiWidth, tempblock + (uiHeightExt-2)*iWidthExtSIMD + 2); + std::copy(tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2, tempblock + (uiHeightExt-3)*iWidthExtSIMD + 2 + uiWidth, tempblock + (uiHeightExt-1)*iWidthExtSIMD + 2); + } + if(!leftAltAvailable) + { + for(int yy = 0; yy<uiHeight; yy++) + { + tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 0] = tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 2]; + tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 1] = tempblock[(iWidthExtSIMD<<1) + yy*iWidthExtSIMD + 2]; + } + } + if(!rightAltAvailable) + { + for(int yy = 0; yy<uiHeight; yy++) + { + tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD] = tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD - 1]; + tempblock[(iWidthExtSIMD<<1) + uiWidthExt-1 + yy*iWidthExtSIMD] = tempblock[(iWidthExtSIMD<<1) + uiWidthExt-2 + yy*iWidthExtSIMD - 1]; + } + } + // All sides are available, easy to just copy corners also. + if(topAltAvailable && leftAltAvailable) + { + tempblock[0] = *(srcPtr - 2*srcStride -2); // a top left corner + tempblock[1] = *(srcPtr - 2*srcStride -1); // b a b|x x + tempblock[iWidthExtSIMD + 0] = *(srcPtr - srcStride -2); // c c d|x x + tempblock[iWidthExtSIMD + 1] = *(srcPtr - srcStride -1); // d ------- + } + else + { + tempblock[0] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left + tempblock[1] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left + tempblock[iWidthExtSIMD + 0] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left + tempblock[iWidthExtSIMD + 1] = tempblock[iWidthExtSIMD*2 + 2]; // extend top left } + if(topAltAvailable && rightAltAvailable) + { + tempblock[iWidthExtSIMD - 2] = *(srcPtr - 2*srcStride + uiWidth); // a + tempblock[iWidthExtSIMD - 1] = *(srcPtr - 2*srcStride + uiWidth + 1); // b + tempblock[iWidthExtSIMD + uiWidthExt - 2] = *(srcPtr - srcStride + uiWidth); // c + tempblock[iWidthExtSIMD + uiWidthExt - 1] = *(srcPtr - srcStride + uiWidth + 1); // d + } + else + { + tempblock[iWidthExtSIMD - 2] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right + tempblock[iWidthExtSIMD - 1] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right + tempblock[iWidthExtSIMD + uiWidthExt - 2] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right + tempblock[iWidthExtSIMD + uiWidthExt - 1] = tempblock[iWidthExtSIMD*2 + uiWidthExt - 3]; // extend top right + } + if(bottomAltAvailable && leftAltAvailable) + { + tempblock[iWidthExtSIMD*(uiHeightExt-2) + 0] = *(srcPtr + uiHeight*srcStride -2); // a + tempblock[iWidthExtSIMD*(uiHeightExt-2) + 1] = *(srcPtr + uiHeight*srcStride -1); // b + tempblock[iWidthExtSIMD*(uiHeightExt-1) + 0] = *(srcPtr + (uiHeight+1)*srcStride -2); // c + tempblock[iWidthExtSIMD*(uiHeightExt-1) + 1] = *(srcPtr + (uiHeight+1)*srcStride -1); // d + } + else + { + tempblock[iWidthExtSIMD*(uiHeightExt-2) + 0] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right + tempblock[iWidthExtSIMD*(uiHeightExt-2) + 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right + tempblock[iWidthExtSIMD*(uiHeightExt-1) + 0] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right + tempblock[iWidthExtSIMD*(uiHeightExt-1) + 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + 2]; // bot avail: mirror left/right + } + if(bottomAltAvailable && rightAltAvailable) + { + tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 2] = *(srcPtr + uiHeight*srcStride + uiWidth); // a + tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 1] = *(srcPtr + uiHeight*srcStride + uiWidth + 1); // b + tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 2] = *(srcPtr + (uiHeight+1)*srcStride + uiWidth); // c + tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 1] = *(srcPtr + (uiHeight+1)*srcStride + uiWidth + 1); // d + } + else + { + tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 2] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; + tempblock[iWidthExtSIMD*(uiHeightExt-2) + uiWidthExt - 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; + tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 2] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; + tempblock[iWidthExtSIMD*(uiHeightExt-1) + uiWidthExt - 1] = tempblock[iWidthExtSIMD*(uiHeightExt-3) + uiWidthExt - 3]; + } + } + m_bilateralFilterDiamond5x5(uiWidth, uiHeight, tempblock, tempblockFiltered, clpRng, recPtr, recStride, iWidthExtSIMD, bfac, bifRoundAdd, bifRoundShift, false, lutRowPtr ); } -const char* BilateralFilter::getFilterLutParameters_chroma( const int size, const PredMode predMode, const int32_t qp, int& bfac, int width_for_strength, int height_for_strength, bool isLumaValid) +void BilateralFilter::clipNotBilaterallyFilteredBlocksChroma(const CPelUnitBuf& src, PelUnitBuf& rec, const ClpRng& clpRng, TransformUnit & currTU, bool isCb) { + PelUnitBuf myRecBuf = currTU.cs->getRecoBuf(currTU); + int chromaIdx = isCb ? COMPONENT_Cb : COMPONENT_Cr; + if(myRecBuf.bufs[chromaIdx].width > 1) + { + // new result = old result (which is SAO-treated already) + diff due to bilateral filtering + myRecBuf.bufs[chromaIdx].copyClip(myRecBuf.bufs[chromaIdx], clpRng); + } + else + { + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + CompArea &compArea = currTU.block(compID); + const unsigned uiHeight = compArea.height; + int recStride = rec.get(compID).stride; + Pel *recPtr = rec.get(compID).bufAt(compArea); - int condition = std::min(width_for_strength, height_for_strength); - - int T1 = 4; - int T2 = 16; - if(!isLumaValid) + for(uint32_t yy = 0; yy < uiHeight; yy++) { - T1 = 128; - T2 = 256; + // new result = old result (which is SAO-treated already) + diff due to bilateral filtering + recPtr[0] = ClipPel<int>(recPtr[0], clpRng); + recPtr += recStride; } + } +} - if(predMode == MODE_INTER) +const char* BilateralFilter::getFilterLutParametersChroma( const int size, const PredMode predMode, const int32_t qp, int& bfac, int widthForStrength, int heightForStrength, bool isLumaValid) +{ + int conditionForStrength = std::min(widthForStrength, heightForStrength); + int T1 = 4; + int T2 = 16; + if(!isLumaValid) + { + T1 = 128; + T2 = 256; + } + if(predMode == MODE_INTER) + { + if(conditionForStrength <= T1) { - if(condition <= T1) - { - bfac = 2; - goto FINISH; - } - if (condition >= T2) - { - bfac = 1; - goto FINISH; - } - if(condition > T1 && condition < T2) - { - bfac = 2; - goto FINISH; - } + bfac = 2; } - else{ - if(condition <= T1) - { - bfac = 3; - goto FINISH; - } - if(condition >= T2) - { - bfac = 1; - goto FINISH; - } - if(condition > T1 && condition < T2) - { - bfac = 2; - goto FINISH; - } + else if (conditionForStrength >= T2) + { + bfac = 1; } - -FINISH: - int sqp = qp; - int qp_min = 17; - int qp_max = 42; - if( sqp < qp_min ) + else { - sqp = qp_min; + bfac = 2; } - if( sqp > qp_max ) + } + else + { + if(conditionForStrength <= T1) { - sqp = qp_max; + bfac = 3; } + else if(conditionForStrength >= T2) + { + bfac = 1; + } + else + { + bfac = 2; + } + } - return m_wBIF_chroma[sqp - 17]; - + int sqp = qp; + int minQP = 17; + int maxQP = 42; + if( sqp < minQP ) + { + sqp = minQP; + } + if( sqp > maxQP ) + { + sqp = maxQP; + } + return m_wBIFChroma[sqp - 17]; } #endif diff --git a/source/Lib/CommonLib/BilateralFilter.h b/source/Lib/CommonLib/BilateralFilter.h index 66b4ceb29fdabb20b8fb03322a45765c40263a60..7b719b5eb41b7e7fda43fea25829d684e61bb529 100755 --- a/source/Lib/CommonLib/BilateralFilter.h +++ b/source/Lib/CommonLib/BilateralFilter.h @@ -51,12 +51,12 @@ public: }; #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER -class CBIFCabacEst +class ChromaBIFCabacEst { public: - virtual ~CBIFCabacEst() {}; - virtual uint64_t getBits_Cb(const Slice& slice, const CBifParams& htdfParams) = 0; - virtual uint64_t getBits_Cr(const Slice& slice, const CBifParams& htdfParams) = 0; + virtual ~ChromaBIFCabacEst() {}; + virtual uint64_t getBitsCb(const Slice& slice, const ChromaBifParams& htdfParams) = 0; + virtual uint64_t getBitsCr(const Slice& slice, const ChromaBifParams& htdfParams) = 0; }; #endif class BilateralFilter @@ -112,7 +112,7 @@ private: }; #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - char m_wBIF_chroma[26][16] = { + char m_wBIFChroma[26][16] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, { 0, 2, 2, 2, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, @@ -163,18 +163,18 @@ public: #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - void bilateralFilterRDOdiamond5x5_chroma(PelBuf& resiBuf, const CPelBuf& predBuf, PelBuf& recoBuf, int32_t qp, const CPelBuf& recIPredBuf, const ClpRng& clpRng, TransformUnit & currTU, bool useReco, bool isCb); + void bilateralFilterRDOdiamond5x5Chroma(PelBuf& resiBuf, const CPelBuf& predBuf, PelBuf& recoBuf, int32_t qp, const CPelBuf& recIPredBuf, const ClpRng& clpRng, TransformUnit & currTU, bool useReco, bool isCb); - void bilateralFilterPicRDOperCTU_chroma(CodingStructure& cs, PelUnitBuf& src, CBIFCabacEst* CBifCABACEstimator, bool isCb); + void bilateralFilterPicRDOperCTUChroma(CodingStructure& cs, PelUnitBuf& src, ChromaBIFCabacEst* ChromaBifCABACEstimator, bool isCb); - void bilateralFilterDiamond5x5_chroma(const CPelUnitBuf& src, PelUnitBuf& rec, int32_t qp, const ClpRng& clpRng, TransformUnit & currTU, bool isCb); + void bilateralFilterDiamond5x5Chroma(const CPelUnitBuf& src, PelUnitBuf& rec, int32_t qp, const ClpRng& clpRng, TransformUnit & currTU, bool isCb); - void clipNotBilaterallyFilteredBlocks_chroma(const CPelUnitBuf& src, PelUnitBuf& rec, const ClpRng& clpRng, TransformUnit & currTU, bool isCb); + void clipNotBilaterallyFilteredBlocksChroma(const CPelUnitBuf& src, PelUnitBuf& rec, const ClpRng& clpRng, TransformUnit & currTU, bool isCb); #if JVET_W0066_CCSAO - void bilateralFilterDiamond5x5NoClip_chroma(const CPelUnitBuf& src, PelUnitBuf& rec, int32_t qp, const ClpRng& clpRng, TransformUnit & currTU, bool isCb); + void bilateralFilterDiamond5x5NoClipChroma(const CPelUnitBuf& src, PelUnitBuf& rec, int32_t qp, const ClpRng& clpRng, TransformUnit & currTU, bool isCb); #endif - const char* getFilterLutParameters_chroma( const int size, const PredMode predMode, const int qp, int& bfac, int width_for_strength, int height_for_strength, bool isLumaValid); + const char* getFilterLutParametersChroma( const int size, const PredMode predMode, const int qp, int& bfac, int widthForStrength, int heightForStrength, bool isLumaValid); #endif #if ENABLE_SIMD_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER_ENABLE_SIMD diff --git a/source/Lib/CommonLib/Contexts.cpp b/source/Lib/CommonLib/Contexts.cpp index 6ec77f40f3b6e9d0d569c35e9d04465df1dbb0b4..17f56ea8806f6d9e7ded42317cbd6a49543bca6c 100644 --- a/source/Lib/CommonLib/Contexts.cpp +++ b/source/Lib/CommonLib/Contexts.cpp @@ -1550,7 +1550,7 @@ const CtxSet ContextSetCfg::BifCtrlFlags = ContextSetCfg::addCtxSet }); #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER -const CtxSet ContextSetCfg::CBifCtrlFlags_Cb = ContextSetCfg::addCtxSet +const CtxSet ContextSetCfg::ChromaBifCtrlFlagsCb = ContextSetCfg::addCtxSet ({ { 39 }, { 39 }, @@ -1559,7 +1559,7 @@ const CtxSet ContextSetCfg::CBifCtrlFlags_Cb = ContextSetCfg::addCtxSet { DWS }, { DWS } }); -const CtxSet ContextSetCfg::CBifCtrlFlags_Cr = ContextSetCfg::addCtxSet +const CtxSet ContextSetCfg::ChromaBifCtrlFlagsCr = ContextSetCfg::addCtxSet ({ { 39 }, { 39 }, @@ -2652,14 +2652,14 @@ const CtxSet ContextSetCfg::BifCtrlFlags = ContextSetCfg::addCtxSet }); #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER -const CtxSet ContextSetCfg::CBifCtrlFlags_Cb = ContextSetCfg::addCtxSet +const CtxSet ContextSetCfg::ChromaBifCtrlFlagsCb = ContextSetCfg::addCtxSet ({ { 39, }, { 39, }, { 39, }, { DWS, }, }); -const CtxSet ContextSetCfg::CBifCtrlFlags_Cr = ContextSetCfg::addCtxSet +const CtxSet ContextSetCfg::ChromaBifCtrlFlagsCr = ContextSetCfg::addCtxSet ({ { 39, }, { 39, }, diff --git a/source/Lib/CommonLib/Contexts.h b/source/Lib/CommonLib/Contexts.h index 1b15ad925b365a09baff4c3b0b1fa8eb43e1b187..b0c0d6da99eaccdc460e8fb5ea8632b924cc7555 100644 --- a/source/Lib/CommonLib/Contexts.h +++ b/source/Lib/CommonLib/Contexts.h @@ -311,8 +311,8 @@ public: static const CtxSet BifCtrlFlags; #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - static const CtxSet CBifCtrlFlags_Cb; - static const CtxSet CBifCtrlFlags_Cr; + static const CtxSet ChromaBifCtrlFlagsCb; + static const CtxSet ChromaBifCtrlFlagsCr; #endif #if JVET_W0066_CCSAO static const CtxSet CcSaoControlIdc; diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp index 6c8b18113365597fe9b436e6f9f95623801ec236..6055d44d632a446f163672bde906aaf986b4c862 100644 --- a/source/Lib/CommonLib/Picture.cpp +++ b/source/Lib/CommonLib/Picture.cpp @@ -43,7 +43,7 @@ BifParams Picture::m_BifParams; #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER -CBifParams Picture::m_CBifParams; +ChromaBifParams Picture::m_ChromaBifParams; #endif #if ENABLE_SPLIT_PARALLELISM diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h index 1aa7a10a8b9ae34be81924080b630d522af7f377..e0972993c4bb2a190b7eaeef18536bd779bdce72 100644 --- a/source/Lib/CommonLib/Picture.h +++ b/source/Lib/CommonLib/Picture.h @@ -315,14 +315,14 @@ public: }; #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - CBifParams& getCBifParam() { return m_CBifParams; } - void resizeBIF_Chroma(unsigned numEntries) + ChromaBifParams& getChromaBifParam() { return m_ChromaBifParams; } + void resizeBIFChroma(unsigned numEntries) { - m_CBifParams.numBlocks = numEntries; - m_CBifParams.ctuOn_Cb.resize(numEntries); - m_CBifParams.ctuOn_Cr.resize(numEntries); - std::fill(m_CBifParams.ctuOn_Cb.begin(), m_CBifParams.ctuOn_Cb.end(), 0); - std::fill(m_CBifParams.ctuOn_Cr.begin(), m_CBifParams.ctuOn_Cr.end(), 0); + m_ChromaBifParams.numBlocks = numEntries; + m_ChromaBifParams.ctuOnCb.resize(numEntries); + m_ChromaBifParams.ctuOnCr.resize(numEntries); + std::fill(m_ChromaBifParams.ctuOnCb.begin(), m_ChromaBifParams.ctuOnCb.end(), 0); + std::fill(m_ChromaBifParams.ctuOnCr.begin(), m_ChromaBifParams.ctuOnCr.end(), 0); } #endif #if ENABLE_QPA @@ -338,7 +338,7 @@ public: static BifParams m_BifParams; #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - static CBifParams m_CBifParams; + static ChromaBifParams m_ChromaBifParams; #endif std::vector<uint8_t> m_alfCtuEnableFlag[MAX_NUM_COMPONENT]; uint8_t* getAlfCtuEnableFlag( int compIdx ) { return m_alfCtuEnableFlag[compIdx].data(); } diff --git a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp index 1f7f3da409d2f37f19a987fa51bd743757274d59..0f40db926f66cbd1a493450e43e7e81fbca63a26 100644 --- a/source/Lib/CommonLib/SampleAdaptiveOffset.cpp +++ b/source/Lib/CommonLib/SampleAdaptiveOffset.cpp @@ -1041,7 +1041,7 @@ void SampleAdaptiveOffset::SAOProcess( CodingStructure& cs, SAOBlkParam* saoBlkP { #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(!cs.pps->getUseBIF() && !cs.pps->getUseCBIF()) + if(!cs.pps->getUseBIF() && !cs.pps->getUseChromaBIF()) #else // Even if we are not doing SAO we might still need to do BIF // so we cannot return even if SAO is never used. @@ -1053,9 +1053,9 @@ void SampleAdaptiveOffset::SAOProcess( CodingStructure& cs, SAOBlkParam* saoBlkP } #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(!cs.pps->getUseCBIF()) + if(!cs.pps->getUseChromaBIF()) { - return; + return; } #else return; @@ -1102,62 +1102,60 @@ void SampleAdaptiveOffset::SAOProcess( CodingStructure& cs, SAOBlkParam* saoBlkP } #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { - bool TU_VALID = false; - bool TU_CBF = false; + bool tuValid = false; + bool tuCBF = false; bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - bool BIF_chroma = false; - CBifParams& CBifParams = cs.picture->getCBifParam(); + ChannelType chType = isDualTree ? CH_C : CH_L; + bool applyChromaBIF = false; + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); // And now we traverse the CTU to do BIF - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) - { - continue; - } - for (auto &currTU : CU::traverseTUs(currCU)) + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) + { + continue; + } + for (auto &currTU : CU::traverseTUs(currCU)) + { + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - - for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) + applyChromaBIF = false; + bool isCb = compIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + bool ctuEnableChromaBIF = isCb ? chromaBifParams.ctuOnCb[ctuRsAddr] : chromaBifParams.ctuOnCr[ctuRsAddr]; + if(!isDualTree) + { + tuValid = currTU.blocks[compIdx].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) { - BIF_chroma = false; - bool isCb = compIdx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - bool CTU_ON = isCb ? CBifParams.ctuOn_Cb[ctuRsAddr] : CBifParams.ctuOn_Cr[ctuRsAddr]; - - if(!isDualTree) - { - TU_VALID = currTU.blocks[compIdx].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero - if(TU_VALID) - { - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17)) && (TU_VALID)); - } - else - { - TU_CBF = TU::getCbf(currTU, compID); - BIF_chroma = (CTU_ON && (( TU_CBF || isInter == false) && (currTU.cu->qp > 17))); - } - if(BIF_chroma) - { - m_bilateralFilter.bilateralFilterDiamond5x5NoClip_chroma(m_tempBuf, rec, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); - } + tuCBF = TU::getCbf(currTU, compID); } + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17)) && (tuValid)); + } + else + { + tuCBF = TU::getCbf(currTU, compID); + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17))); + } + if(applyChromaBIF) + { + m_bilateralFilter.bilateralFilterDiamond5x5NoClipChroma(m_tempBuf, rec, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); + } } + } } - } + } #endif #else #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseBIF() || cs.pps->getUseCBIF()) + if(cs.pps->getUseBIF() || cs.pps->getUseChromaBIF()) #else if(cs.pps->getUseBIF()) #endif @@ -1176,18 +1174,21 @@ void SampleAdaptiveOffset::SAOProcess( CodingStructure& cs, SAOBlkParam* saoBlkP if(!bAllDisabled && myCtbOffset.modeIdc != SAO_MODE_OFF) clipLumaIfNoBilat = true; #if JVET_X0071_CHROMA_BILATERAL_FILTER - SAOOffset& myCtbOffset_Cb = mySAOblkParam[1]; - SAOOffset& myCtbOffset_Cr = mySAOblkParam[2]; - CBifParams& CBifParams = cs.picture->getCBifParam(); - - bool clipChromaIfNoBilat_Cb = false; - bool clipChromaIfNoBilat_Cr = false; + SAOOffset& myCtbOffsetCb = mySAOblkParam[1]; + SAOOffset& myCtbOffsetCr = mySAOblkParam[2]; + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); - if(!bAllDisabled && myCtbOffset_Cb.modeIdc != SAO_MODE_OFF) - clipChromaIfNoBilat_Cb = true; - if(!bAllDisabled && myCtbOffset_Cr.modeIdc != SAO_MODE_OFF) - clipChromaIfNoBilat_Cr = true; + bool clipChromaIfNoBilatCb = false; + bool clipChromaIfNoBilatCr = false; + if(!bAllDisabled && myCtbOffsetCb.modeIdc != SAO_MODE_OFF) + { + clipChromaIfNoBilatCb = true; + } + if(!bAllDisabled && myCtbOffsetCr.modeIdc != SAO_MODE_OFF) + { + clipChromaIfNoBilatCr = true; + } if(cs.pps->getUseBIF()) { #endif @@ -1215,97 +1216,97 @@ void SampleAdaptiveOffset::SAOProcess( CodingStructure& cs, SAOBlkParam* saoBlkP } // BIF LUMA is disabled else { - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) + { + for (auto &currTU : CU::traverseTUs(currCU)) { - for (auto &currTU : CU::traverseTUs(currCU)) - { - if(clipLumaIfNoBilat) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Y), currTU); - } - } + if(clipLumaIfNoBilat) + { + m_bilateralFilter.clipNotBilaterallyFilteredBlocks(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Y), currTU); + } } + } } - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { - bool TU_VALID = false; - bool TU_CBF = false; - bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - bool BIF_chroma = false; - // And now we traverse the CTU to do BIF - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + bool tuValid = false; + bool tuCBF = false; + bool isDualTree = CS::isDualITree(cs); + ChannelType chType = isDualTree ? CH_C : CH_L; + bool applyChromaBIF = false; + // And now we traverse the CTU to do BIF + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) + { + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) + continue; + } + for (auto &currTU : CU::traverseTUs(currCU)) + { + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) + { + bool isCb = compIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + bool ctuEnableChromaBIF = isCb ? chromaBifParams.ctuOnCb[ctuRsAddr] : chromaBifParams.ctuOnCr[ctuRsAddr]; + applyChromaBIF = false; + if(!isDualTree) { - continue; + tuValid = currTU.blocks[compIdx].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) + { + tuCBF = TU::getCbf(currTU, compID); + } + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17)) && (tuValid)); } - for (auto &currTU : CU::traverseTUs(currCU)) + else { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) - { - bool isCb = compIdx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - bool CTU_ON = isCb ? CBifParams.ctuOn_Cb[ctuRsAddr] : CBifParams.ctuOn_Cr[ctuRsAddr]; - - BIF_chroma = false; - if(!isDualTree) - { - TU_VALID = currTU.blocks[compIdx].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero - if(TU_VALID) - { - TU_CBF =TU::getCbf(currTU, compID); - } - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17)) && (TU_VALID)); - } - else - { - TU_CBF = TU::getCbf(currTU, compID); - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17))); - } - - if(BIF_chroma) - { - m_bilateralFilter.bilateralFilterDiamond5x5_chroma(m_tempBuf, rec, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); - } - else - { - bool use_clip = isCb ? clipChromaIfNoBilat_Cb : clipChromaIfNoBilat_Cr; - if(use_clip && currTU.blocks[compIdx].valid()) - m_bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(m_tempBuf, rec, cs.slice->clpRng(compID), currTU, isCb); - } - } + tuCBF = TU::getCbf(currTU, compID); + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17))); } + if(applyChromaBIF) + { + m_bilateralFilter.bilateralFilterDiamond5x5Chroma(m_tempBuf, rec, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); + } + else + { + bool useClip = isCb ? clipChromaIfNoBilatCb : clipChromaIfNoBilatCr; + if(useClip && currTU.blocks[compIdx].valid()) + { + m_bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(m_tempBuf, rec, cs.slice->clpRng(compID), currTU, isCb); + } + } + } } + } }// BIF chroma is disabled else { - bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; + bool isDualTree = CS::isDualITree(cs); + ChannelType chType = isDualTree ? CH_C : CH_L; - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) + { + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) - { - continue; - } - for (auto &currTU : CU::traverseTUs(currCU)) - { - if(clipChromaIfNoBilat_Cb && currTU.blocks[COMPONENT_Cb].valid()) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Cb), currTU, true); - } - if(clipChromaIfNoBilat_Cr && currTU.blocks[COMPONENT_Cr].valid()) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Cr), currTU, false); - } - } + continue; + } + for (auto &currTU : CU::traverseTUs(currCU)) + { + if(clipChromaIfNoBilatCb && currTU.blocks[COMPONENT_Cb].valid()) + { + m_bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Cb), currTU, true); + } + if(clipChromaIfNoBilatCr && currTU.blocks[COMPONENT_Cr].valid()) + { + m_bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Cr), currTU, false); } + } } + } #endif } else @@ -1317,7 +1318,7 @@ void SampleAdaptiveOffset::SAOProcess( CodingStructure& cs, SAOBlkParam* saoBlkP #if JVET_X0071_CHROMA_BILATERAL_FILTER if( !bAllDisabled ) { - offsetCTUnoClip( area, m_tempBuf, rec, cs.picture->getSAO()[ctuRsAddr], cs); + offsetCTUnoClip( area, m_tempBuf, rec, cs.picture->getSAO()[ctuRsAddr], cs); } SAOBlkParam mySAOblkParam = cs.picture->getSAO()[ctuRsAddr]; @@ -1326,115 +1327,115 @@ void SampleAdaptiveOffset::SAOProcess( CodingStructure& cs, SAOBlkParam* saoBlkP bool clipLumaIfNoBilat = false; if(!bAllDisabled && myCtbOffset.modeIdc != SAO_MODE_OFF) { - clipLumaIfNoBilat = true; + clipLumaIfNoBilat = true; } - SAOOffset& myCtbOffset_Cb = mySAOblkParam[1]; - SAOOffset& myCtbOffset_Cr = mySAOblkParam[2]; - CBifParams& CBifParams = cs.picture->getCBifParam(); + SAOOffset& myCtbOffsetCb = mySAOblkParam[1]; + SAOOffset& myCtbOffsetCr = mySAOblkParam[2]; + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); - bool clipChromaIfNoBilat_Cb = false; - bool clipChromaIfNoBilat_Cr = false; + bool clipChromaIfNoBilatCb = false; + bool clipChromaIfNoBilatCr = false; - if(!bAllDisabled && myCtbOffset_Cb.modeIdc != SAO_MODE_OFF) + if(!bAllDisabled && myCtbOffsetCb.modeIdc != SAO_MODE_OFF) { - clipChromaIfNoBilat_Cb = true; + clipChromaIfNoBilatCb = true; } - if(!bAllDisabled && myCtbOffset_Cr.modeIdc != SAO_MODE_OFF) + if(!bAllDisabled && myCtbOffsetCr.modeIdc != SAO_MODE_OFF) { - clipChromaIfNoBilat_Cr = true; + clipChromaIfNoBilatCr = true; } for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) { - for (auto &currTU : CU::traverseTUs(currCU)) + for (auto &currTU : CU::traverseTUs(currCU)) + { + if(clipLumaIfNoBilat) { - if(clipLumaIfNoBilat) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Y), currTU); - } + m_bilateralFilter.clipNotBilaterallyFilteredBlocks(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Y), currTU); } + } } - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { - bool TU_VALID = false; - bool TU_CBF = false; - bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - bool BIF_chroma = false; - // And now we traverse the CTU to do BIF - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + bool tuValid = false; + bool tuCBF = false; + bool isDualTree = CS::isDualITree(cs); + ChannelType chType = isDualTree ? CH_C : CH_L; + bool applyChromaBIF = false; + // And now we traverse the CTU to do BIF + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) + { + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) + continue; + } + for (auto &currTU : CU::traverseTUs(currCU)) + { + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) + { + bool isCb = compIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + bool ctuEnableChromaBIF = isCb ? chromaBifParams.ctuOnCb[ctuRsAddr] : chromaBifParams.ctuOnCr[ctuRsAddr]; + + applyChromaBIF = false; + if(!isDualTree) { - continue; + tuValid = currTU.blocks[compIdx].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) + { + tuCBF = TU::getCbf(currTU, compID); + } + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17)) && (tuValid)); } - for (auto &currTU : CU::traverseTUs(currCU)) + else { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) - { - bool isCb = compIdx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - bool CTU_ON = isCb ? CBifParams.ctuOn_Cb[ctuRsAddr] : CBifParams.ctuOn_Cr[ctuRsAddr]; - - BIF_chroma = false; - if(!isDualTree) - { - TU_VALID = currTU.blocks[compIdx].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero - if(TU_VALID) - { - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17)) && (TU_VALID)); - } - else - { - TU_CBF = TU::getCbf(currTU, compID); - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17))); - } - if(BIF_chroma) - { - m_bilateralFilter.bilateralFilterDiamond5x5_chroma(m_tempBuf, rec, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); - } - else - { - bool use_clip = isCb ? clipChromaIfNoBilat_Cb : clipChromaIfNoBilat_Cr; - if(use_clip && currTU.blocks[compIdx].valid()) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(m_tempBuf, rec, cs.slice->clpRng(compID), currTU, true); - } - } - } + tuCBF = TU::getCbf(currTU, compID); + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17))); + } + if(applyChromaBIF) + { + m_bilateralFilter.bilateralFilterDiamond5x5Chroma(m_tempBuf, rec, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); } + else + { + bool useClip = isCb ? clipChromaIfNoBilatCb : clipChromaIfNoBilatCr; + if(useClip && currTU.blocks[compIdx].valid()) + { + m_bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(m_tempBuf, rec, cs.slice->clpRng(compID), currTU, true); + } + } + } } + } }// BIF chroma off else { - bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + bool isDualTree = CS::isDualITree(cs); + ChannelType chType = isDualTree ? CH_C : CH_L; + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) + { + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) - { - continue; - } - for (auto &currTU : CU::traverseTUs(currCU)) - { - if(clipChromaIfNoBilat_Cb && currTU.blocks[COMPONENT_Cb].valid()) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Cb), currTU, true); - } - if(clipChromaIfNoBilat_Cr && currTU.blocks[COMPONENT_Cr].valid()) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Cr), currTU, false); - } - } + continue; } + for (auto &currTU : CU::traverseTUs(currCU)) + { + if(clipChromaIfNoBilatCb && currTU.blocks[COMPONENT_Cb].valid()) + { + m_bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Cb), currTU, true); + } + if(clipChromaIfNoBilatCr && currTU.blocks[COMPONENT_Cr].valid()) + { + m_bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(m_tempBuf, rec, cs.slice->clpRng(COMPONENT_Cr), currTU, false); + } + } + } } #else offsetCTU( area, m_tempBuf, rec, cs.picture->getSAO()[ctuRsAddr], cs); @@ -1501,13 +1502,13 @@ void SampleAdaptiveOffset::jointClipSaoBifCcSao(CodingStructure& cs) { #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (!cs.sps->getSAOEnabledFlag() && !cs.pps->getUseBIF() && !cs.pps->getUseCBIF() && !cs.sps->getCCSAOEnabledFlag()) + if (!cs.sps->getSAOEnabledFlag() && !cs.pps->getUseBIF() && !cs.pps->getUseChromaBIF() && !cs.sps->getCCSAOEnabledFlag()) #else if (!cs.sps->getSAOEnabledFlag() && !cs.pps->getUseBIF() && !cs.sps->getCCSAOEnabledFlag()) #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (!cs.sps->getSAOEnabledFlag() && !cs.sps->getCCSAOEnabledFlag() && !cs.pps->getUseCBIF()) + if (!cs.sps->getSAOEnabledFlag() && !cs.sps->getCCSAOEnabledFlag() && !cs.pps->getUseChromaBIF()) #else if (!cs.sps->getSAOEnabledFlag() && !cs.sps->getCCSAOEnabledFlag()) #endif @@ -1575,56 +1576,54 @@ void SampleAdaptiveOffset::jointClipSaoBifCcSao(CodingStructure& cs) } } #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { if(compIdx == COMPONENT_Cb || compIdx == COMPONENT_Cr) { - CBifParams& CBifParams = cs.picture->getCBifParam(); - bool isCb = compIdx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - - bool TU_VALID = false; - bool TU_CBF = false; - bool CTU_ON = false; - bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - bool BIF_chroma = false; - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); + bool isCb = compIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + + bool tuValid = false; + bool tuCBF = false; + bool ctuEnableChromaBIF = false; + bool isDualTree = CS::isDualITree(cs); + ChannelType chType = isDualTree ? CH_C : CH_L; + bool applyChromaBIF = false; + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) + { + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) - { - continue; - } - - for (auto &currTU : CU::traverseTUs(currCU)) + continue; + } + for (auto &currTU : CU::traverseTUs(currCU)) + { + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + //Cb or Cr + applyChromaBIF = false; + ctuEnableChromaBIF = isCb ? chromaBifParams.ctuOnCb[ctuRsAddr] : chromaBifParams.ctuOnCr[ctuRsAddr]; + if(!isDualTree) + { + tuValid = currTU.blocks[compIdx].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - //Cb or Cr - BIF_chroma = false; - CTU_ON = isCb ? CBifParams.ctuOn_Cb[ctuRsAddr] : CBifParams.ctuOn_Cr[ctuRsAddr]; - - if(!isDualTree) - { - TU_VALID = currTU.blocks[compIdx].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero - if(TU_VALID) - { - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17)) && (TU_VALID)); - } - else - { - TU_CBF = TU::getCbf(currTU, compID); - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17))); - } - if(BIF_chroma) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(m_tempBuf, dstYuv, cs.slice->clpRng(compID) , currTU, isCb); - } + tuCBF = TU::getCbf(currTU, compID); } + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17)) && (tuValid)); + } + else + { + tuCBF = TU::getCbf(currTU, compID); + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17))); + } + if(applyChromaBIF) + { + m_bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(m_tempBuf, dstYuv, cs.slice->clpRng(compID) , currTU, isCb); + } } + } } } #endif diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index cee991028a6cbf47c947c6302d2ff18aba805f31..8901747ce1bac04192523108e5516b55eccbac34 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -3400,9 +3400,9 @@ PPS::PPS() , m_BIFQPOffset (0) #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER -, m_CBIF (false) -, m_CBIFStrength (1) -, m_CBIFQPOffset (0) +, m_chromaBIF (false) +, m_chromaBIFStrength (1) +, m_chromaBIFQPOffset (0) #endif , pcv (NULL) { diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 72035ff1d78af5e73009260791b688718573e241..3db6d8442d66a444ac4045029392cfc5516d510e 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -2304,9 +2304,9 @@ private: int m_BIFQPOffset; #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - bool m_CBIF; - int m_CBIFStrength; - int m_CBIFQPOffset; + bool m_chromaBIF; + int m_chromaBIFStrength; + int m_chromaBIFQPOffset; #endif public: @@ -2512,12 +2512,12 @@ public: int getBIFQPOffset() const { return m_BIFQPOffset; } #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - void setUseCBIF( bool b) { m_CBIF = b; } - bool getUseCBIF() const { return m_CBIF; } - void setCBIFStrength( int val) { m_CBIFStrength = val; } - int getCBIFStrength() const { return m_CBIFStrength; } - void setCBIFQPOffset( int val) { m_CBIFQPOffset = val; } - int getCBIFQPOffset() const { return m_CBIFQPOffset; } + void setUseChromaBIF( bool b) { m_chromaBIF = b; } + bool getUseChromaBIF() const { return m_chromaBIF; } + void setChromaBIFStrength( int val) { m_chromaBIFStrength = val; } + int getChromaBIFStrength() const { return m_chromaBIFStrength; } + void setChromaBIFQPOffset( int val) { m_chromaBIFQPOffset = val; } + int getChromaBIFQPOffset() const { return m_chromaBIFQPOffset; } #endif void setDeblockingFilterControlPresentFlag( bool val ) { m_deblockingFilterControlPresentFlag = val; } bool getDeblockingFilterControlPresentFlag() const { return m_deblockingFilterControlPresentFlag; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index a0834f8991561fea2a00794a131563a1eb152eb6..4a3e90208f596ed875eff52d0ca73dedddbf132c 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -1241,16 +1241,16 @@ public: }; #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER -class CBifParams +class ChromaBifParams { public: - int frmOn_Cb; // slice_bif_enabled_flag for chroma - int frmOn_Cr; // slice_bif_enabled_flag for chroma - int allCtuOn_Cb; // slice_bif_all_ctb_enabled_flag for chroma - int allCtuOn_Cr; // slice_bif_all_ctb_enabled_flag for chroma - int numBlocks; - std::vector<int> ctuOn_Cb; // bif_ctb_flag[][] for chroma - std::vector<int> ctuOn_Cr; // bif_ctb_flag[][] for chroma + int frmOnCb; // slice_bif_enabled_flag for chroma + int frmOnCr; // slice_bif_enabled_flag for chroma + int allCtuOnCb; // slice_bif_all_ctb_enabled_flag for chroma + int allCtuOnCr; // slice_bif_all_ctb_enabled_flag for chroma + int numBlocks; + std::vector<int> ctuOnCb; // bif_ctb_flag[][] for chroma + std::vector<int> ctuOnCr; // bif_ctb_flag[][] for chroma }; #endif diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 0b878c7d6dadebf784a19b536320a6f09ab5e6bf..9451ae55ce2de770d9e4a68adbd275cc81fd7a75 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -375,7 +375,7 @@ void CABACReader::sao( CodingStructure& cs, unsigned ctuRsAddr ) #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(!(cs.pps->getUseBIF() || cs.sps->getSAOEnabledFlag() || !(cs.pps->getUseCBIF()))) + if(!(cs.pps->getUseBIF() || cs.sps->getSAOEnabledFlag() || cs.pps->getUseChromaBIF())) #else // If neither BIF nor SAO is enabled, we can return. if(!(cs.pps->getUseBIF() || cs.sps->getSAOEnabledFlag())) @@ -387,7 +387,7 @@ void CABACReader::sao( CodingStructure& cs, unsigned ctuRsAddr ) SAOBlkParam& sao_ctu_pars = cs.picture->getSAO()[ctuRsAddr]; #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(!(cs.pps->getUseCBIF() || cs.sps->getSAOEnabledFlag())) + if(!(cs.pps->getUseChromaBIF() || cs.sps->getSAOEnabledFlag())) { return; } @@ -606,136 +606,138 @@ void CABACReader::bif(CodingStructure& cs, unsigned ctuRsAddr) } #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER -void CABACReader::Cbif_Cb(CodingStructure& cs) +void CABACReader::chromaBifCb(CodingStructure& cs) { - int width = cs.picture->lwidth(); - int height = cs.picture->lheight(); + int width = cs.picture->lwidth(); + int height = cs.picture->lheight(); - int block_width = cs.pcv->maxCUWidth; - int block_height = cs.pcv->maxCUHeight; + int blockWidth = cs.pcv->maxCUWidth; + int blockHeight = cs.pcv->maxCUHeight; - int width_in_blocks = width / block_width + (width % block_width != 0); - int height_in_blocks = height / block_height + (height % block_height != 0); + int widthInBlocks = width / blockWidth + (width % blockWidth != 0); + int heightInBlocks = height / blockHeight + (height % blockHeight != 0); - for (int i = 0; i < width_in_blocks * height_in_blocks; i++) - { - Cbif_Cb(cs, i); - } + for (int i = 0; i < widthInBlocks * heightInBlocks; i++) + { + chromaBifCb(cs, i); + } } -void CABACReader::Cbif_Cb(CodingStructure& cs, unsigned ctuRsAddr) +void CABACReader::chromaBifCb(CodingStructure& cs, unsigned ctuRsAddr) { - const PPS& pps = *cs.pps; - - if (!pps.getUseCBIF()) - { - return; - } - - CBifParams& CBifParams = cs.picture->getCBifParam(); + const PPS& pps = *cs.pps; - if (ctuRsAddr == 0) - { - int width = cs.picture->lwidth(); - int height = cs.picture->lheight(); - int block_width = cs.pcv->maxCUWidth; - int block_height = cs.pcv->maxCUHeight; + if (!pps.getUseChromaBIF()) + { + return; + } + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); + if (ctuRsAddr == 0) + { + int width = cs.picture->lwidth(); + int height = cs.picture->lheight(); + int blockWidth = cs.pcv->maxCUWidth; + int blockHeight = cs.pcv->maxCUHeight; - int width_in_blocks = width / block_width + (width % block_width != 0); - int height_in_blocks = height / block_height + (height % block_height != 0); - int num_blocks = width_in_blocks * height_in_blocks; - CBifParams.numBlocks = num_blocks; - CBifParams.ctuOn_Cb.resize(num_blocks); - std::fill(CBifParams.ctuOn_Cb.begin(), CBifParams.ctuOn_Cb.end(), 0); - } - if (ctuRsAddr == 0) + int widthInBlocks = width / blockWidth + (width % blockWidth != 0); + int heightInBlocks = height / blockHeight + (height % blockHeight != 0); + int numBlocks = widthInBlocks * heightInBlocks; + chromaBifParams.numBlocks = numBlocks; + chromaBifParams.ctuOnCb.resize(numBlocks); + std::fill(chromaBifParams.ctuOnCb.begin(), chromaBifParams.ctuOnCb.end(), 0); + } + if (ctuRsAddr == 0) + { + chromaBifParams.allCtuOnCb = m_BinDecoder.decodeBinEP(); + if (chromaBifParams.allCtuOnCb == 0) { - CBifParams.allCtuOn_Cb = m_BinDecoder.decodeBinEP(); - if (CBifParams.allCtuOn_Cb == 0) - CBifParams.frmOn_Cb = m_BinDecoder.decodeBinEP(); + chromaBifParams.frmOnCb = m_BinDecoder.decodeBinEP(); } - int i = ctuRsAddr; - if (CBifParams.allCtuOn_Cb) + } + int i = ctuRsAddr; + if (chromaBifParams.allCtuOnCb) + { + chromaBifParams.ctuOnCb[i] = 1; + } + else + { + if (chromaBifParams.frmOnCb) { - CBifParams.ctuOn_Cb[i] = 1; + chromaBifParams.ctuOnCb[i] = m_BinDecoder.decodeBin(Ctx::ChromaBifCtrlFlagsCb()); } else { - if (CBifParams.frmOn_Cb) - { - CBifParams.ctuOn_Cb[i] = m_BinDecoder.decodeBin(Ctx::CBifCtrlFlags_Cb()); - } - else - { - CBifParams.ctuOn_Cb[i] = 0; - } + chromaBifParams.ctuOnCb[i] = 0; } + } } -void CABACReader::Cbif_Cr(CodingStructure& cs) +void CABACReader::chromaBifCr(CodingStructure& cs) { - int width = cs.picture->lwidth(); - int height = cs.picture->lheight(); + int width = cs.picture->lwidth(); + int height = cs.picture->lheight(); - int block_width = cs.pcv->maxCUWidth; - int block_height = cs.pcv->maxCUHeight; + int blockWidth = cs.pcv->maxCUWidth; + int blockHeight = cs.pcv->maxCUHeight; - int width_in_blocks = width / block_width + (width % block_width != 0); - int height_in_blocks = height / block_height + (height % block_height != 0); + int widthInBlocks = width / blockWidth + (width % blockWidth != 0); + int heightInBlocks = height / blockHeight + (height % blockHeight != 0); - for (int i = 0; i < width_in_blocks * height_in_blocks; i++) - { - Cbif_Cr(cs, i); - } + for (int i = 0; i < widthInBlocks * heightInBlocks; i++) + { + chromaBifCr(cs, i); + } } -void CABACReader::Cbif_Cr(CodingStructure& cs, unsigned ctuRsAddr) +void CABACReader::chromaBifCr(CodingStructure& cs, unsigned ctuRsAddr) { - const PPS& pps = *cs.pps; + const PPS& pps = *cs.pps; - if (!pps.getUseCBIF()) - { - return; - } + if (!pps.getUseChromaBIF()) + { + return; + } - CBifParams& CBifParams = cs.picture->getCBifParam(); + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); - if (ctuRsAddr == 0) - { - int width = cs.picture->lwidth(); - int height = cs.picture->lheight(); - int block_width = cs.pcv->maxCUWidth; - int block_height = cs.pcv->maxCUHeight; + if (ctuRsAddr == 0) + { + int width = cs.picture->lwidth(); + int height = cs.picture->lheight(); + int blockWidth = cs.pcv->maxCUWidth; + int blockHeight = cs.pcv->maxCUHeight; - int width_in_blocks = width / block_width + (width % block_width != 0); - int height_in_blocks = height / block_height + (height % block_height != 0); - int num_blocks = width_in_blocks * height_in_blocks; - CBifParams.numBlocks = num_blocks; - CBifParams.ctuOn_Cr.resize(num_blocks); - std::fill(CBifParams.ctuOn_Cr.begin(), CBifParams.ctuOn_Cr.end(), 0); - } - if (ctuRsAddr == 0) + int widthInBlocks = width / blockWidth + (width % blockWidth != 0); + int heightInBlocks = height / blockHeight + (height % blockHeight != 0); + int numBlocks = widthInBlocks * heightInBlocks; + chromaBifParams.numBlocks = numBlocks; + chromaBifParams.ctuOnCr.resize(numBlocks); + std::fill(chromaBifParams.ctuOnCr.begin(), chromaBifParams.ctuOnCr.end(), 0); + } + if (ctuRsAddr == 0) + { + chromaBifParams.allCtuOnCr = m_BinDecoder.decodeBinEP(); + if (chromaBifParams.allCtuOnCr == 0) { - CBifParams.allCtuOn_Cr = m_BinDecoder.decodeBinEP(); - if (CBifParams.allCtuOn_Cr == 0) - CBifParams.frmOn_Cr = m_BinDecoder.decodeBinEP(); + chromaBifParams.frmOnCr = m_BinDecoder.decodeBinEP(); } - int i = ctuRsAddr; - if (CBifParams.allCtuOn_Cr) + } + int i = ctuRsAddr; + if (chromaBifParams.allCtuOnCr) + { + chromaBifParams.ctuOnCr[i] = 1; + } + else + { + if (chromaBifParams.frmOnCr) { - CBifParams.ctuOn_Cr[i] = 1; + chromaBifParams.ctuOnCr[i] = m_BinDecoder.decodeBin(Ctx::ChromaBifCtrlFlagsCr()); } else { - if (CBifParams.frmOn_Cr) - { - CBifParams.ctuOn_Cr[i] = m_BinDecoder.decodeBin(Ctx::CBifCtrlFlags_Cr()); - } - else - { - CBifParams.ctuOn_Cr[i] = 0; - } + chromaBifParams.ctuOnCr[i] = 0; } + } } #endif diff --git a/source/Lib/DecoderLib/CABACReader.h b/source/Lib/DecoderLib/CABACReader.h index 0754d5f6152a25a710a7d84ea765a641a0638f3c..986ebf1d470fffa11b150288e924188c37053ddb 100644 --- a/source/Lib/DecoderLib/CABACReader.h +++ b/source/Lib/DecoderLib/CABACReader.h @@ -73,10 +73,10 @@ public: void bif (CodingStructure& cs, unsigned ctuRsAddr); #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - void Cbif_Cb (CodingStructure& cs); - void Cbif_Cb (CodingStructure& cs, unsigned ctuRsAddr); - void Cbif_Cr (CodingStructure& cs); - void Cbif_Cr (CodingStructure& cs, unsigned ctuRsAddr); + void chromaBifCb (CodingStructure& cs); + void chromaBifCb (CodingStructure& cs, unsigned ctuRsAddr); + void chromaBifCr (CodingStructure& cs); + void chromaBifCr (CodingStructure& cs, unsigned ctuRsAddr); #endif #if JVET_W0066_CCSAO diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 1cb97cdb728fef1111d6e477add049984bbf4265..e85fd072a8a021d874c4a69a5f66b06ee0d43951 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -194,7 +194,7 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri { #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if ( pic->cs->sps->getSAOEnabledFlag() || pic->cs->pps->getUseBIF() || pic->cs->pps->getUseCBIF()) + if ( pic->cs->sps->getSAOEnabledFlag() || pic->cs->pps->getUseBIF() || pic->cs->pps->getUseChromaBIF()) #else // Since the per-CTU BIF parameter is stored in SAO, we need to // do this copy even if SAO=0, if BIF=1. @@ -202,7 +202,7 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if ( pic->cs->sps->getSAOEnabledFlag() || pic->cs->pps->getUseCBIF()) + if ( pic->cs->sps->getSAOEnabledFlag() || pic->cs->pps->getUseChromaBIF()) #else if ( pic->cs->sps->getSAOEnabledFlag() ) #endif @@ -261,7 +261,7 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri pcDecLib->executeLoopFilters(); #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if ( pic->cs->sps->getSAOEnabledFlag() || pic->cs->pps->getUseBIF() || pic->cs->pps->getUseCBIF()) + if ( pic->cs->sps->getSAOEnabledFlag() || pic->cs->pps->getUseBIF() || pic->cs->pps->getUseChromaBIF()) #else // Since the per-CTU BIF parameter is stored in SAO, we need to // do this copy even if SAO=0, if BIF=1. @@ -269,7 +269,7 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if ( pic->cs->sps->getSAOEnabledFlag() || pic->cs->pps->getUseCBIF()) + if ( pic->cs->sps->getSAOEnabledFlag() || pic->cs->pps->getUseChromaBIF()) #else if ( pic->cs->sps->getSAOEnabledFlag() ) #endif @@ -718,13 +718,13 @@ void DecLib::executeLoopFilters() #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if( cs.sps->getSAOEnabledFlag() || cs.pps->getUseBIF() || cs.pps->getUseCBIF()) + if( cs.sps->getSAOEnabledFlag() || cs.pps->getUseBIF() || cs.pps->getUseChromaBIF()) #else if( cs.sps->getSAOEnabledFlag() || cs.pps->getUseBIF()) #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if( cs.sps->getSAOEnabledFlag() || cs.pps->getUseCBIF()) + if( cs.sps->getSAOEnabledFlag() || cs.pps->getUseChromaBIF()) #else if( cs.sps->getSAOEnabledFlag() ) #endif @@ -1745,7 +1745,7 @@ void DecLib::xActivateParameterSets( const InputNALUnit nalu ) // Recursive structure m_cCuDecoder.init( &m_cTrQuant, &m_cIntraPred, &m_cInterPred ); -#if !JVET_V0094_BILATERAL_FILTER +#if !JVET_V0094_BILATERAL_FILTER && !JVET_X0071_CHROMA_BILATERAL_FILTER if (sps->getUseLmcs()) #endif { diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp index cca8fdb9da3f7d158b34907b5585462d49442c27..c4bae4749469d8c411b906b288b607aac11a3c0a 100644 --- a/source/Lib/DecoderLib/DecSlice.cpp +++ b/source/Lib/DecoderLib/DecSlice.cpp @@ -246,8 +246,8 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb #if JVET_X0071_CHROMA_BILATERAL_FILTER if (ctuRsAddr == 0) { - cabacReader.Cbif_Cb(cs); - cabacReader.Cbif_Cr(cs); + cabacReader.chromaBifCb(cs); + cabacReader.chromaBifCr(cs); } #endif cabacReader.coding_tree_unit( cs, ctuArea, pic->m_prevQP, ctuRsAddr ); diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 3b4e32f6bce2eff1f07678155e01f1479a486e08..59295dd8c65f4d17ecb35f418bc19a535f31a0ef 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -811,11 +811,11 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS ) } #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - READ_FLAG( uiCode, "chroma bilateral_filter_flag" ); pcPPS->setUseCBIF(uiCode != 0) ; - if(pcPPS->getUseCBIF()) + READ_FLAG( uiCode, "chroma bilateral_filter_flag" ); pcPPS->setUseChromaBIF(uiCode != 0) ; + if(pcPPS->getUseChromaBIF()) { - READ_CODE( 2, uiCode, "chroma bilateral_filter_strength" ); pcPPS->setCBIFStrength( uiCode); - READ_SVLC( iCode, "chroma bilateral_filter_qp_offset" ); pcPPS->setCBIFQPOffset( iCode); + READ_CODE( 2, uiCode, "chroma bilateral_filter_strength" ); pcPPS->setChromaBIFStrength( uiCode); + READ_SVLC( iCode, "chroma bilateral_filter_qp_offset" ); pcPPS->setChromaBIFQPOffset( iCode); } #endif diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index b7676a28e4ed8fb6f38901a24c228967b6c218db..49e941741fd0441763d4b31d42aff4f5a883e5cd 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -179,66 +179,64 @@ void CABACWriter::bif(const Slice& slice, const BifParams& bifParams, unsigned c } #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER -void CABACWriter::Cbif_Cb(const Slice& slice, const CBifParams& CBifParams) +void CABACWriter::chromaBifCb(const Slice& slice, const ChromaBifParams& chromaBifParams) { - for (int i = 0; i < CBifParams.numBlocks; ++i) - { - Cbif_Cb(slice, CBifParams, i); - } + for (int i = 0; i < chromaBifParams.numBlocks; ++i) + { + chromaBifCb(slice, chromaBifParams, i); + } } -void CABACWriter::Cbif_Cb(const Slice& slice, const CBifParams& CBifParams, unsigned ctuRsAddr) +void CABACWriter::chromaBifCb(const Slice& slice, const ChromaBifParams& chromaBifParams, unsigned ctuRsAddr) { - const PPS& pps = *slice.getPPS(); - if (!pps.getUseCBIF()) - { - return; - } - - if (ctuRsAddr == 0) - { - m_BinEncoder.encodeBinEP(CBifParams.allCtuOn_Cb); - if (CBifParams.allCtuOn_Cb == 0) - { - m_BinEncoder.encodeBinEP(CBifParams.frmOn_Cb); - } - } - if (CBifParams.allCtuOn_Cb == 0 && CBifParams.frmOn_Cb) + const PPS& pps = *slice.getPPS(); + if (!pps.getUseChromaBIF()) + { + return; + } + if (ctuRsAddr == 0) + { + m_BinEncoder.encodeBinEP(chromaBifParams.allCtuOnCb); + if (chromaBifParams.allCtuOnCb == 0) { - int i = ctuRsAddr; - m_BinEncoder.encodeBin(CBifParams.ctuOn_Cb[i], Ctx::CBifCtrlFlags_Cb()); + m_BinEncoder.encodeBinEP(chromaBifParams.frmOnCb); } + } + if (chromaBifParams.allCtuOnCb == 0 && chromaBifParams.frmOnCb) + { + int i = ctuRsAddr; + m_BinEncoder.encodeBin(chromaBifParams.ctuOnCb[i], Ctx::ChromaBifCtrlFlagsCb()); + } } -void CABACWriter::Cbif_Cr(const Slice& slice, const CBifParams& CBifParams) +void CABACWriter::chromaBifCr(const Slice& slice, const ChromaBifParams& chromaBifParams) { - for (int i = 0; i < CBifParams.numBlocks; ++i) - { - Cbif_Cr(slice, CBifParams, i); - } + for (int i = 0; i < chromaBifParams.numBlocks; ++i) + { + chromaBifCr(slice, chromaBifParams, i); + } } -void CABACWriter::Cbif_Cr(const Slice& slice, const CBifParams& CBifParams, unsigned ctuRsAddr) +void CABACWriter::chromaBifCr(const Slice& slice, const ChromaBifParams& chromaBifParams, unsigned ctuRsAddr) { - const PPS& pps = *slice.getPPS(); - if (!pps.getUseCBIF()) - { - return; - } - - if (ctuRsAddr == 0) - { - m_BinEncoder.encodeBinEP(CBifParams.allCtuOn_Cr); - if (CBifParams.allCtuOn_Cr == 0) - { - m_BinEncoder.encodeBinEP(CBifParams.frmOn_Cr); - } - } - if (CBifParams.allCtuOn_Cr == 0 && CBifParams.frmOn_Cr) + const PPS& pps = *slice.getPPS(); + if (!pps.getUseChromaBIF()) + { + return; + } + if (ctuRsAddr == 0) + { + m_BinEncoder.encodeBinEP(chromaBifParams.allCtuOnCr); + if (chromaBifParams.allCtuOnCr == 0) { - int i = ctuRsAddr; - m_BinEncoder.encodeBin(CBifParams.ctuOn_Cr[i], Ctx::CBifCtrlFlags_Cr()); + m_BinEncoder.encodeBinEP(chromaBifParams.frmOnCr); } + } + if (chromaBifParams.allCtuOnCr == 0 && chromaBifParams.frmOnCr) + { + int i = ctuRsAddr; + m_BinEncoder.encodeBin(chromaBifParams.ctuOnCr[i], Ctx::ChromaBifCtrlFlagsCr()); + } } #endif diff --git a/source/Lib/EncoderLib/CABACWriter.h b/source/Lib/EncoderLib/CABACWriter.h index 88a9e0e6181d50d15dedf4244ac81976d7a20ebb..a565b108bccede0cfff3293eb1b95484cccf3b04 100644 --- a/source/Lib/EncoderLib/CABACWriter.h +++ b/source/Lib/EncoderLib/CABACWriter.h @@ -85,10 +85,10 @@ public: void bif (const Slice& slice, const BifParams& BifParams, unsigned ctuRsAddr); #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - void Cbif_Cb (const Slice& slice, const CBifParams& CBifParams); - void Cbif_Cb (const Slice& slice, const CBifParams& CBifParams, unsigned ctuRsAddr); - void Cbif_Cr (const Slice& slice, const CBifParams& CBifParams); - void Cbif_Cr (const Slice& slice, const CBifParams& CBifParams, unsigned ctuRsAddr); + void chromaBifCb (const Slice& slice, const ChromaBifParams& chromaBifParams); + void chromaBifCb (const Slice& slice, const ChromaBifParams& chromaBifParams, unsigned ctuRsAddr); + void chromaBifCr (const Slice& slice, const ChromaBifParams& chromaBifParams); + void chromaBifCr (const Slice& slice, const ChromaBifParams& chromaBifParams, unsigned ctuRsAddr); #endif #if JVET_W0066_CCSAO void codeCcSaoControlIdc ( uint8_t idcVal, CodingStructure &cs, const ComponentID compID, const int curIdx, diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 3d4231fec42f169aed224c5dfcb6ed27c317a6df..a7695ad0ea5a7ec2e76a8cdc06f74aec2ab0d0a7 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -837,9 +837,9 @@ protected: int m_BIFQPOffset; #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - bool m_CBIF; - int m_CBIFStrength; - int m_CBIFQPOffset; + bool m_chromaBIF; + int m_chromaBIFStrength; + int m_chromaBIFQPOffset; #endif bool m_ccalf; @@ -1349,12 +1349,12 @@ public: int getBIFQPOffset () const { return m_BIFQPOffset; } #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - void setUseCBIF ( bool b ) { m_CBIF = b; } - bool getUseCBIF () const { return m_CBIF; } - void setCBIFStrength ( int val ) { m_CBIFStrength = val; } - int getCBIFStrength () const { return m_CBIFStrength; } - void setCBIFQPOffset ( int val ) { m_CBIFQPOffset = val; } - int getCBIFQPOffset () const { return m_CBIFQPOffset; } + void setUseChromaBIF ( bool b ) { m_chromaBIF = b; } + bool getUseChromaBIF () const { return m_chromaBIF; } + void setChromaBIFStrength ( int val ) { m_chromaBIFStrength = val; } + int getChromaBIFStrength () const { return m_chromaBIFStrength; } + void setChromaBIFQPOffset ( int val ) { m_chromaBIFQPOffset = val; } + int getChromaBIFQPOffset () const { return m_chromaBIFQPOffset; } #endif #if MULTI_HYP_PRED void setNumMHPCandsToTest(int i) { m_numMHPCandsToTest = i; } diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index a3a852edd6def99e6e30ee15c48e048bf9b14da9..64c14cc3f3089f32aa4c7aa82625a0dfa640207e 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -8822,49 +8822,46 @@ void EncCu::xCalDebCost( CodingStructure &cs, Partitioner &partitioner, bool cal } #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()){ - bool TU_VALID = false; - bool TU_CBF = false; - bool isDualTree = CS::isDualITree(cs); - bool chroma_valid = cu->Cb().valid() && cu->Cr().valid(); - bool BIF_chroma = false; - for (auto &currTU : CU::traverseTUs(*cu)) + if(cs.pps->getUseChromaBIF()) + { + bool tuValid = false; + bool tuCBF = false; + bool isDualTree = CS::isDualITree(cs); + bool chromaValid = cu->Cb().valid() && cu->Cr().valid(); + bool applyChromaBIF = false; + for (auto &currTU : CU::traverseTUs(*cu)) + { + bool isInter = (cu->predMode == MODE_INTER) ? true : false; + for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) { - bool isInter = (cu->predMode == MODE_INTER) ? true : false; - - for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) + bool isCb = compIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + applyChromaBIF = false; + if(!isDualTree && chromaValid) + { + tuValid = currTU.blocks[compIdx].valid(); + tuCBF = false; + if(tuValid) { - bool isCb = compIdx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - - BIF_chroma = false; - if(!isDualTree && chroma_valid) - { - TU_VALID = currTU.blocks[compIdx].valid(); - TU_CBF = false; - if(TU_VALID) - { - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = ((TU_CBF || isInter == false) && (currTU.cu->qp > 17) && (TU_VALID)); - } - - if(isDualTree && chroma_valid) - { - TU_CBF = TU::getCbf(currTU, compID); - BIF_chroma = ((TU_CBF || isInter == false) && (currTU.cu->qp > 17)); - } - - if (BIF_chroma) - { - CompArea &compArea = currTU.block(compID); - PelBuf recBuf = picDbBuf.getBuf(compArea); - PelBuf recIPredBuf = recBuf; - - m_bilateralFilter->bilateralFilterRDOdiamond5x5_chroma(recBuf, recBuf, recBuf, currTU.cu->qp, recIPredBuf, cs.slice->clpRng(compID), currTU, true, isCb); - } + tuCBF = TU::getCbf(currTU, compID); } + applyChromaBIF = ((tuCBF || isInter == false) && (currTU.cu->qp > 17) && (tuValid)); + } + + if(isDualTree && chromaValid) + { + tuCBF = TU::getCbf(currTU, compID); + applyChromaBIF = ((tuCBF || isInter == false) && (currTU.cu->qp > 17)); + } + if (applyChromaBIF) + { + CompArea &compArea = currTU.block(compID); + PelBuf recBuf = picDbBuf.getBuf(compArea); + PelBuf recIPredBuf = recBuf; + m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(recBuf, recBuf, recBuf, currTU.cu->qp, recIPredBuf, cs.slice->clpRng(compID), currTU, true, isCb); + } } + } } #endif @@ -9493,56 +9490,52 @@ void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&best } } #if JVET_X0071_CHROMA_BILATERAL_FILTER - const CompArea &area_chroma = cu.blocks[compID]; - CompArea tmpArea_chroma(compID, area_chroma.chromaFormat, Position(0, 0), area_chroma.size()); + const CompArea &areaChroma = cu.blocks[compID]; + CompArea tmpAreaChroma(compID, areaChroma.chromaFormat, Position(0, 0), areaChroma.size()); PelBuf tmpRecChroma; if(isChroma(compID)) { - tmpRecChroma = m_tmpStorageLCU->getBuf(tmpArea_chroma); - tmpRecChroma.copyFrom(reco); + tmpRecChroma = m_tmpStorageLCU->getBuf(tmpAreaChroma); + tmpRecChroma.copyFrom(reco); } - if(tempCS->pps->getUseCBIF() && isChroma(compID) && (cu.qp > 17)) + if(tempCS->pps->getUseChromaBIF() && isChroma(compID) && (cu.qp > 17)) { - bool TU_VALID = false; - bool TU_CBF = false; - bool isDualTree = CS::isDualITree(*tempCS); - bool chroma_valid = cu.Cb().valid() && cu.Cr().valid(); - bool BIF_chroma = false; - - for (auto &currTU : CU::traverseTUs(cu)) + bool tuValid = false; + bool tuCBF = false; + bool isDualTree = CS::isDualITree(*tempCS); + bool chromaValid = cu.Cb().valid() && cu.Cr().valid(); + bool applyChromaBIF = false; + for (auto &currTU : CU::traverseTUs(cu)) + { + Position tuPosInCu = currTU.chromaPos() - cu.chromaPos(); + PelBuf tmpSubBuf = tmpRecChroma.subBuf(tuPosInCu, currTU.chromaSize()); + bool isInter = (cu.predMode == MODE_INTER) ? true : false; + bool isCb = compID == COMPONENT_Cb ? true : false; + applyChromaBIF = false; + if(!isDualTree && chromaValid) { - Position tuPosInCu = currTU.chromaPos() - cu.chromaPos(); - PelBuf tmpSubBuf = tmpRecChroma.subBuf(tuPosInCu, currTU.chromaSize()); - - bool isInter = (cu.predMode == MODE_INTER) ? true : false; - bool isCb = compID == COMPONENT_Cb ? true : false; - BIF_chroma = false; - if(!isDualTree && chroma_valid) - { - TU_VALID = currTU.blocks[compID].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero - - if(TU_VALID) - { - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = (( TU_CBF || isInter == false) && (currTU.cu->qp > 17) && (TU_VALID)); - - } + tuValid = currTU.blocks[compID].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) + { + tuCBF = TU::getCbf(currTU, compID); + } + applyChromaBIF = (( tuCBF || isInter == false) && (currTU.cu->qp > 17) && (tuValid)); + } - if(isDualTree && chroma_valid) - { - BIF_chroma = ((TU::getCbf(currTU, compID) || isInter == false) && (currTU.cu->qp > 17)); - } + if(isDualTree && chromaValid) + { + applyChromaBIF = ((TU::getCbf(currTU, compID) || isInter == false) && (currTU.cu->qp > 17)); + } - if(BIF_chroma) - { - CompArea compArea = currTU.blocks[compID]; - PelBuf recIPredBuf = tempCS->slice->getPic()->getRecoBuf(compArea); - m_bilateralFilter->bilateralFilterRDOdiamond5x5_chroma(tmpSubBuf, tmpSubBuf, tmpSubBuf, currTU.cu->qp, recIPredBuf, tempCS->slice->clpRng(compID), currTU, true, isCb); - } + if(applyChromaBIF) + { + CompArea compArea = currTU.blocks[compID]; + PelBuf recIPredBuf = tempCS->slice->getPic()->getRecoBuf(compArea); + m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpSubBuf, tmpSubBuf, tmpSubBuf, currTU.cu->qp, recIPredBuf, tempCS->slice->clpRng(compID), currTU, true, isCb); } + } } #endif @@ -9558,13 +9551,13 @@ void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&best else { #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(isChroma(compID) && tempCS->pps->getUseCBIF()) + if(isChroma(compID) && tempCS->pps->getUseChromaBIF()) { - finalDistortion += m_pcRdCost->getDistPart(org, tmpRecChroma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma); + finalDistortion += m_pcRdCost->getDistPart(org, tmpRecChroma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma); } else { - finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma ); + finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma ); } #else finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma ); @@ -9578,53 +9571,52 @@ void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&best } #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - const CompArea &area_chroma = cu.blocks[compID]; - CompArea tmpArea_chroma(compID, area_chroma.chromaFormat, Position(0, 0), area_chroma.size()); + const CompArea &areaChroma = cu.blocks[compID]; + CompArea tmpAreaChroma(compID, areaChroma.chromaFormat, Position(0, 0), areaChroma.size()); PelBuf tmpRecChroma; if(isChroma(compID)) { - tmpRecChroma = m_tmpStorageLCU->getBuf(tmpArea_chroma); - tmpRecChroma.copyFrom(reco); + tmpRecChroma = m_tmpStorageLCU->getBuf(tmpAreaChroma); + tmpRecChroma.copyFrom(reco); } - if(tempCS->pps->getUseCBIF() && isChroma(compID) && (cu.qp > 17)) + if(tempCS->pps->getUseChromaBIF() && isChroma(compID) && (cu.qp > 17)) { - bool TU_VALID = false; - bool TU_CBF = false; - bool isDualTree = CS::isDualITree(*tempCS); - bool chroma_valid = cu.Cb().valid() && cu.Cr().valid(); - bool BIF_chroma = false; - - for (auto &currTU : CU::traverseTUs(cu)) - { - Position tuPosInCu = currTU.chromaPos() - cu.chromaPos(); - PelBuf tmpSubBuf = tmpRecChroma.subBuf(tuPosInCu, currTU.chromaSize()); - - bool isInter = (cu.predMode == MODE_INTER) ? true : false; - bool isCb = compID == COMPONENT_Cb ? true : false; - BIF_chroma = false; - if(!isDualTree && chroma_valid) - { - TU_VALID = currTU.blocks[compID].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero + bool tuValid = false; + bool tuCBF = false; + bool isDualTree = CS::isDualITree(*tempCS); + bool chromaValid = cu.Cb().valid() && cu.Cr().valid(); + bool applyChromaBIF = false; - if(TU_VALID){ - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = (( TU_CBF || isInter == false) && (currTU.cu->qp > 17) && (TU_VALID)); - } - - if(isDualTree && chroma_valid){ - BIF_chroma = ((TU::getCbf(currTU, compID) || isInter == false) && (currTU.cu->qp > 17)); - } + for (auto &currTU : CU::traverseTUs(cu)) + { + Position tuPosInCu = currTU.chromaPos() - cu.chromaPos(); + PelBuf tmpSubBuf = tmpRecChroma.subBuf(tuPosInCu, currTU.chromaSize()); - if(BIF_chroma) - { - CompArea compArea = currTU.blocks[compID]; - PelBuf recIPredBuf = tempCS->slice->getPic()->getRecoBuf(compArea); - m_bilateralFilter->bilateralFilterRDOdiamond5x5_chroma(tmpSubBuf, tmpSubBuf, tmpSubBuf, currTU.cu->qp, recIPredBuf, tempCS->slice->clpRng(compID), currTU, true, isCb); - } + bool isInter = (cu.predMode == MODE_INTER) ? true : false; + bool isCb = compID == COMPONENT_Cb ? true : false; + applyChromaBIF = false; + if(!isDualTree && chromaValid) + { + tuValid = currTU.blocks[compID].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) + { + tuCBF = TU::getCbf(currTU, compID); + } + applyChromaBIF = ((tuCBF || isInter == false) && (currTU.cu->qp > 17) && (tuValid)); + } + if(isDualTree && chromaValid) + { + applyChromaBIF = ((TU::getCbf(currTU, compID) || isInter == false) && (currTU.cu->qp > 17)); + } + if(applyChromaBIF) + { + CompArea compArea = currTU.blocks[compID]; + PelBuf recIPredBuf = tempCS->slice->getPic()->getRecoBuf(compArea); + m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpSubBuf, tmpSubBuf, tmpSubBuf, currTU.cu->qp, recIPredBuf, tempCS->slice->clpRng(compID), currTU, true, isCb); } + } } #endif #if WCG_EXT @@ -9642,7 +9634,7 @@ void EncCu::xReuseCachedResult( CodingStructure *&tempCS, CodingStructure *&best else { #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(isChroma(compID) && tempCS->pps->getUseCBIF()) + if(isChroma(compID) && tempCS->pps->getUseChromaBIF()) { finalDistortion += m_pcRdCost->getDistPart(org, tmpRecChroma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma); } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 3f60318f86b2dadef92036cb8badd50d8c178786..adf9dc97ce7573024d8078d8e41c0cbf9f623252 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -1969,28 +1969,27 @@ public: }; #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER -class CBIFCabacEstImp : public CBIFCabacEst +class ChromaBIFCabacEstImp : public ChromaBIFCabacEst { - CABACWriter* CABACEstimator; + CABACWriter* CABACEstimator; public: - CBIFCabacEstImp(CABACWriter* _CABACEstimator) : CABACEstimator(_CABACEstimator) {}; - virtual ~CBIFCabacEstImp() {}; + ChromaBIFCabacEstImp(CABACWriter* _CABACEstimator) : CABACEstimator(_CABACEstimator) {}; + virtual ~ChromaBIFCabacEstImp() {}; - virtual uint64_t getBits_Cb(const Slice& slice, const CBifParams& htdfParams) - { - CABACEstimator->initCtxModels(slice); - CABACEstimator->resetBits(); - CABACEstimator->Cbif_Cb(slice, htdfParams); - return CABACEstimator->getEstFracBits(); - } - - virtual uint64_t getBits_Cr(const Slice& slice, const CBifParams& htdfParams) - { - CABACEstimator->initCtxModels(slice); - CABACEstimator->resetBits(); - CABACEstimator->Cbif_Cr(slice, htdfParams); - return CABACEstimator->getEstFracBits(); - } + virtual uint64_t getBitsCb(const Slice& slice, const ChromaBifParams& chromaBifParams) + { + CABACEstimator->initCtxModels(slice); + CABACEstimator->resetBits(); + CABACEstimator->chromaBifCb(slice, chromaBifParams); + return CABACEstimator->getEstFracBits(); + } + virtual uint64_t getBitsCr(const Slice& slice, const ChromaBifParams& chromaBifParams) + { + CABACEstimator->initCtxModels(slice); + CABACEstimator->resetBits(); + CABACEstimator->chromaBifCr(slice, chromaBifParams); + return CABACEstimator->getEstFracBits(); + } }; #endif @@ -2823,7 +2822,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, #endif #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF() || pcSlice->getPPS()->getUseCBIF()) + if (pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF() || pcSlice->getPPS()->getUseChromaBIF()) #else // BIF happens in SAO code so this needs to be done // even if SAO=0 if BIF=1. @@ -2831,7 +2830,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseCBIF()) + if (pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseChromaBIF()) #else if (pcSlice->getSPS()->getSAOEnabledFlag()) #endif @@ -3097,6 +3096,9 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, if( pcSlice->getSPS()->getSAOEnabledFlag() #if JVET_V0094_BILATERAL_FILTER || pcSlice->getPPS()->getUseBIF() +#endif +#if JVET_X0071_CHROMA_BILATERAL_FILTER + || pcSlice->getPPS()->getUseChromaBIF() #endif ) { @@ -3180,14 +3182,14 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF() || pcSlice->getPPS()->getUseCBIF()) + if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF() || pcSlice->getPPS()->getUseChromaBIF()) #else // We need to do this step if at least one of BIF or SAO are enabled. if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseBIF()) #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseCBIF()) + if( pcSlice->getSPS()->getSAOEnabledFlag() || pcSlice->getPPS()->getUseChromaBIF()) #else if( pcSlice->getSPS()->getSAOEnabledFlag() ) #endif @@ -3199,7 +3201,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, BIFCabacEstImp est(m_pcEncLib->getCABACEncoder()->getCABACEstimator(cs.slice->getSPS())); #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - CBIFCabacEstImp CBIF_est(m_pcEncLib->getCABACEncoder()->getCABACEstimator(cs.slice->getSPS())); + ChromaBIFCabacEstImp chromaBifEst(m_pcEncLib->getCABACEncoder()->getCABACEstimator(cs.slice->getSPS())); #endif m_pcSAO->SAOProcess( cs, sliceEnabled, pcSlice->getLambdas(), @@ -3211,7 +3213,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, , &est #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - , &CBIF_est + , &chromaBifEst #endif ); //assign SAO slice header diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 737a7f9086ede49aaf0a7c000bc461dfc4773b25..1d1f11d180bf7db71fd13a165bfa155d892c5d4e 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -171,13 +171,13 @@ void EncLib::create( const int layerId ) #if JVET_V0094_BILATERAL_FILTER #if JVET_W0066_CCSAO #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (m_bUseSAO || m_BIF || m_CCSAO || m_CBIF) + if (m_bUseSAO || m_BIF || m_CCSAO || m_chromaBIF) #else if (m_bUseSAO || m_BIF || m_CCSAO) #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (m_bUseSAO || m_BIF || m_CBIF) + if (m_bUseSAO || m_BIF || m_chromaBIF) #else if (m_bUseSAO || m_BIF) #endif @@ -185,13 +185,13 @@ void EncLib::create( const int layerId ) #else #if JVET_W0066_CCSAO #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (m_bUseSAO || m_CCSAO || m_CBIF) + if (m_bUseSAO || m_CCSAO || m_chromaBIF) #else if (m_bUseSAO || m_CCSAO) #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (m_bUseSAO || m_CBIF) + if (m_bUseSAO || m_chromaBIF) #else if (m_bUseSAO) #endif @@ -1956,9 +1956,9 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps) pps.setBIFQPOffset ( m_BIFQPOffset ); #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - pps.setUseCBIF ( m_CBIF ); - pps.setCBIFStrength ( m_CBIFStrength ); - pps.setCBIFQPOffset ( m_CBIFQPOffset ); + pps.setUseChromaBIF ( m_chromaBIF ); + pps.setChromaBIFStrength ( m_chromaBIFStrength ); + pps.setChromaBIFQPOffset ( m_chromaBIFQPOffset ); #endif if ( getDeblockingFilterMetric() ) diff --git a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp index 5a5df72140281ad9e599b1b525e5a4d971cbebb8..95adc17180974651e2b5fd5327de7f57e54a7239 100644 --- a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp +++ b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.cpp @@ -282,7 +282,7 @@ void EncSampleAdaptiveOffset::SAOProcess( CodingStructure& cs, bool* sliceEnable ,BIFCabacEst* BifCABACEstimator #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - ,CBIFCabacEst* CBifCABACEstimator + ,ChromaBIFCabacEst* ChromaBifCABACEstimator #endif ) { @@ -331,44 +331,45 @@ void EncSampleAdaptiveOffset::SAOProcess( CodingStructure& cs, bool* sliceEnable //int CtuIdx = 0; #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()){ + if(cs.pps->getUseChromaBIF()) + { const PreCalcValues& pcv = *cs.pcv; - CBifParams& CBifParams = cs.picture->getCBifParam(); + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); int width = cs.picture->lwidth(); int height = cs.picture->lheight(); - int block_width = pcv.maxCUWidth; - int block_height = pcv.maxCUHeight; + int blockWidth = pcv.maxCUWidth; + int blockHeight = pcv.maxCUHeight; - int width_in_blocks = width / block_width + (width % block_width != 0); - int height_in_blocks = height / block_height + (height % block_height != 0); + int widthInBlocks = width / blockWidth + (width % blockWidth != 0); + int heightInBlocks = height / blockHeight + (height % blockHeight != 0); - CBifParams.numBlocks = width_in_blocks * height_in_blocks; + chromaBifParams.numBlocks = widthInBlocks * heightInBlocks; - CBifParams.ctuOn_Cb.resize(CBifParams.numBlocks); - CBifParams.ctuOn_Cr.resize(CBifParams.numBlocks); - std::fill(CBifParams.ctuOn_Cb.begin(), CBifParams.ctuOn_Cb.end(), 0); - std::fill(CBifParams.ctuOn_Cr.begin(), CBifParams.ctuOn_Cr.end(), 0); - CBifParams.frmOn_Cb = 0; - CBifParams.frmOn_Cr = 0; - CBifParams.allCtuOn_Cb = 0; - CBifParams.allCtuOn_Cr = 0; + chromaBifParams.ctuOnCb.resize(chromaBifParams.numBlocks); + chromaBifParams.ctuOnCr.resize(chromaBifParams.numBlocks); + std::fill(chromaBifParams.ctuOnCb.begin(), chromaBifParams.ctuOnCb.end(), 0); + std::fill(chromaBifParams.ctuOnCr.begin(), chromaBifParams.ctuOnCr.end(), 0); + chromaBifParams.frmOnCb = 0; + chromaBifParams.frmOnCr = 0; + chromaBifParams.allCtuOnCb = 0; + chromaBifParams.allCtuOnCr = 0; - if (CBifParams.frmOn_Cb == 0) + if (chromaBifParams.frmOnCb == 0) { - std::fill(CBifParams.ctuOn_Cb.begin(), CBifParams.ctuOn_Cb.end(), 0); + std::fill(chromaBifParams.ctuOnCb.begin(), chromaBifParams.ctuOnCb.end(), 0); } - else if (CBifParams.allCtuOn_Cb) + else if (chromaBifParams.allCtuOnCb) { - std::fill(CBifParams.ctuOn_Cb.begin(), CBifParams.ctuOn_Cb.end(), 1); + std::fill(chromaBifParams.ctuOnCb.begin(), chromaBifParams.ctuOnCb.end(), 1); } - if (CBifParams.frmOn_Cr == 0) + if (chromaBifParams.frmOnCr == 0) { - std::fill(CBifParams.ctuOn_Cr.begin(), CBifParams.ctuOn_Cr.end(), 0); + std::fill(chromaBifParams.ctuOnCr.begin(), chromaBifParams.ctuOnCr.end(), 0); } - else if (CBifParams.allCtuOn_Cr) + else if (chromaBifParams.allCtuOnCr) { - std::fill(CBifParams.ctuOn_Cr.begin(), CBifParams.ctuOn_Cr.end(), 1); + std::fill(chromaBifParams.ctuOnCr.begin(), chromaBifParams.ctuOnCr.end(), 1); } } #endif @@ -376,19 +377,19 @@ void EncSampleAdaptiveOffset::SAOProcess( CodingStructure& cs, bool* sliceEnable #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER BilateralFilter bilateralFilter; - if(!cs.sps->getSAOEnabledFlag() && (cs.pps->getUseBIF() || cs.pps->getUseCBIF())) + if(!cs.sps->getSAOEnabledFlag() && (cs.pps->getUseBIF() || cs.pps->getUseChromaBIF())) { bilateralFilter.create(); if(cs.pps->getUseBIF()) { bilateralFilter.bilateralFilterPicRDOperCTU(cs, src, BifCABACEstimator); // Filters from src to res } - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { - //Cb - bilateralFilter.bilateralFilterPicRDOperCTU_chroma(cs, src, CBifCABACEstimator, true); - //Cr - bilateralFilter.bilateralFilterPicRDOperCTU_chroma(cs, src, CBifCABACEstimator, false); + //Cb + bilateralFilter.bilateralFilterPicRDOperCTUChroma(cs, src, ChromaBifCABACEstimator, true); + //Cr + bilateralFilter.bilateralFilterPicRDOperCTUChroma(cs, src, ChromaBifCABACEstimator, false); } bilateralFilter.destroy(); return; @@ -411,18 +412,18 @@ void EncSampleAdaptiveOffset::SAOProcess( CodingStructure& cs, bool* sliceEnable #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - BilateralFilter bilateralFilter; - if(!cs.sps->getSAOEnabledFlag() && cs.pps->getUseCBIF()) - { - bilateralFilter.create(); - //Cb - bilateralFilter.bilateralFilterPicRDOperCTU_chroma(cs, src, CBifCABACEstimator, true); - //Cr - bilateralFilter.bilateralFilterPicRDOperCTU_chroma(cs, src, CBifCABACEstimator, false); - bilateralFilter.destroy(); - return; - } - memcpy(m_lambda, lambdas, sizeof(m_lambda)); + BilateralFilter bilateralFilter; + if(!cs.sps->getSAOEnabledFlag() && cs.pps->getUseChromaBIF()) + { + bilateralFilter.create(); + //Cb + bilateralFilter.bilateralFilterPicRDOperCTUChroma(cs, src, ChromaBifCABACEstimator, true); + //Cr + bilateralFilter.bilateralFilterPicRDOperCTUChroma(cs, src, ChromaBifCABACEstimator, false); + bilateralFilter.destroy(); + return; + } + memcpy(m_lambda, lambdas, sizeof(m_lambda)); #else //do nothing #endif @@ -431,19 +432,19 @@ void EncSampleAdaptiveOffset::SAOProcess( CodingStructure& cs, bool* sliceEnable //collect statistics #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseBIF() || cs.pps->getUseCBIF()) + if(cs.pps->getUseBIF() || cs.pps->getUseChromaBIF()) { bilateralFilter.create(); if(cs.pps->getUseBIF()) { bilateralFilter.bilateralFilterPicRDOperCTU(cs, src, BifCABACEstimator); // Filters from src to res' } - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { - //Cb - bilateralFilter.bilateralFilterPicRDOperCTU_chroma(cs, src, CBifCABACEstimator, true); - //Cr - bilateralFilter.bilateralFilterPicRDOperCTU_chroma(cs, src, CBifCABACEstimator, false); + //Cb + bilateralFilter.bilateralFilterPicRDOperCTUChroma(cs, src, ChromaBifCABACEstimator, true); + //Cr + bilateralFilter.bilateralFilterPicRDOperCTUChroma(cs, src, ChromaBifCABACEstimator, false); } getStatistics(m_statData, org, src, res, cs); bilateralFilter.destroy(); @@ -468,13 +469,13 @@ void EncSampleAdaptiveOffset::SAOProcess( CodingStructure& cs, bool* sliceEnable #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { bilateralFilter.create(); //Cb - bilateralFilter.bilateralFilterPicRDOperCTU_chroma(cs, src, CBifCABACEstimator, true); + bilateralFilter.bilateralFilterPicRDOperCTUChroma(cs, src, ChromaBifCABACEstimator, true); //Cr - bilateralFilter.bilateralFilterPicRDOperCTU_chroma(cs, src, CBifCABACEstimator, false); + bilateralFilter.bilateralFilterPicRDOperCTUChroma(cs, src, ChromaBifCABACEstimator, false); getStatistics(m_statData, org, src, res, cs); bilateralFilter.destroy(); } @@ -494,7 +495,7 @@ void EncSampleAdaptiveOffset::SAOProcess( CodingStructure& cs, bool* sliceEnable #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseBIF() || cs.pps->getUseCBIF()) + if(cs.pps->getUseBIF() || cs.pps->getUseChromaBIF()) { res.copyFrom(src); } @@ -505,7 +506,7 @@ void EncSampleAdaptiveOffset::SAOProcess( CodingStructure& cs, bool* sliceEnable #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { res.copyFrom(src); } @@ -1174,7 +1175,7 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn codedParams[ctuRsAddr].reset(); #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(!cs.pps->getUseBIF() && !cs.pps->getUseCBIF()) + if(!cs.pps->getUseBIF() && !cs.pps->getUseChromaBIF()) { continue; } @@ -1190,7 +1191,7 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(!cs.pps->getUseCBIF()) + if(!cs.pps->getUseChromaBIF()) { continue; } @@ -1402,60 +1403,59 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn } #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { - CBifParams& CBifParams = cs.picture->getCBifParam(); + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); - bool TU_VALID = false; - bool TU_CBF = false; + bool tuValid = false; + bool tuCBF = false; bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - bool BIF_chroma = false; + ChannelType chType = isDualTree ? CH_C : CH_L; + bool applyChromaBIF = false; - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid){ - continue; - } - for (auto &currTU : CU::traverseTUs(currCU)) + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid){ + continue; + } + for (auto &currTU : CU::traverseTUs(currCU)) + { + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + for(int compIdx = COMPONENT_Cb ; compIdx < MAX_NUM_COMPONENT; compIdx++) { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - for(int compIdx = COMPONENT_Cb ; compIdx < MAX_NUM_COMPONENT; compIdx++) + bool isCb = compIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb :COMPONENT_Cr; + bool ctuEnableChromaBIF = isCb ? chromaBifParams.ctuOnCb[ctuRsAddr] : chromaBifParams.ctuOnCr[ctuRsAddr]; + applyChromaBIF = false; + if(!isDualTree) + { + tuValid = currTU.blocks[compIdx].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) { - bool isCb = compIdx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb :COMPONENT_Cr; - bool CTU_ON = isCb ? CBifParams.ctuOn_Cb[ctuRsAddr] : CBifParams.ctuOn_Cr[ctuRsAddr]; - - BIF_chroma = false; - if(!isDualTree) - { - TU_VALID = currTU.blocks[compIdx].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero - if(TU_VALID) - { - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17)) && (TU_VALID)); - } - else - { - TU_CBF = TU::getCbf(currTU, compID); - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17))); - } - if(BIF_chroma) - { - bilateralFilter.bilateralFilterDiamond5x5NoClip_chroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); - } + tuCBF = TU::getCbf(currTU, compID); } + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17)) && (tuValid)); + } + else + { + tuCBF = TU::getCbf(currTU, compID); + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17))); + } + if(applyChromaBIF) + { + bilateralFilter.bilateralFilterDiamond5x5NoClipChroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); + } } + } } - } + } #endif #else #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseBIF() || cs.pps->getUseCBIF()) + if(cs.pps->getUseBIF() || cs.pps->getUseChromaBIF()) #else if(cs.pps->getUseBIF()) #endif @@ -1474,20 +1474,20 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn if(myCtbOffset.modeIdc != SAO_MODE_OFF) clipLumaIfNoBilat = true; #if JVET_X0071_CHROMA_BILATERAL_FILTER - SAOOffset& myCtbOffset_Cb = mySAOblkParam[1]; - SAOOffset& myCtbOffset_Cr = mySAOblkParam[2]; - CBifParams& CBifParams = cs.picture->getCBifParam(); + SAOOffset& myCtbOffsetCb = mySAOblkParam[1]; + SAOOffset& myCtbOffsetCr = mySAOblkParam[2]; + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); - bool clipChromaIfNoBilat_Cb = false; - bool clipChromaIfNoBilat_Cr = false; + bool clipChromaIfNoBilatCb = false; + bool clipChromaIfNoBilatCr = false; - if(myCtbOffset_Cb.modeIdc != SAO_MODE_OFF) + if(myCtbOffsetCb.modeIdc != SAO_MODE_OFF) { - clipChromaIfNoBilat_Cb = true; + clipChromaIfNoBilatCb = true; } - if(myCtbOffset_Cr.modeIdc != SAO_MODE_OFF) + if(myCtbOffsetCr.modeIdc != SAO_MODE_OFF) { - clipChromaIfNoBilat_Cr = true; + clipChromaIfNoBilatCr = true; } if(cs.pps->getUseBIF()) { @@ -1513,102 +1513,99 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn } #if JVET_X0071_CHROMA_BILATERAL_FILTER } // BIF LUMA is disabled - else{ - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) + else + { + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) + { + for (auto &currTU : CU::traverseTUs(currCU)) { - for (auto &currTU : CU::traverseTUs(currCU)) - { - if(clipLumaIfNoBilat) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Y), currTU); - } - } + if(clipLumaIfNoBilat) + { + m_bilateralFilter.clipNotBilaterallyFilteredBlocks(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Y), currTU); + } } + } } - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { - bool TU_VALID = false; - bool TU_CBF = false; + bool tuValid = false; + bool tuCBF = false; bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - bool BIF_chroma = false; + ChannelType chType = isDualTree ? CH_C : CH_L; + bool applyChromaBIF = false; - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) - { - continue; - } - - for (auto &currTU : CU::traverseTUs(currCU)) + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) + { + continue; + } + for (auto &currTU : CU::traverseTUs(currCU)) + { + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - - for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) + bool isCb = compIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + bool ctuEnableChromaBIF = isCb ? chromaBifParams.ctuOnCb[ctuRsAddr] : chromaBifParams.ctuOnCr[ctuRsAddr]; + applyChromaBIF = false; + if(!isDualTree) + { + tuValid = currTU.blocks[compIdx].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) { - bool isCb = compIdx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - bool CTU_ON = isCb ? CBifParams.ctuOn_Cb[ctuRsAddr] : CBifParams.ctuOn_Cr[ctuRsAddr]; - - BIF_chroma = false; - if(!isDualTree) - { - TU_VALID = currTU.blocks[compIdx].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero - - if(TU_VALID) - { - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17)) && (TU_VALID)); - } - else - { - TU_CBF = TU::getCbf(currTU, compID); - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17))); - } - if(BIF_chroma) - { - m_bilateralFilter.bilateralFilterDiamond5x5_chroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); - } - else - { - bool use_clip = isCb ? clipChromaIfNoBilat_Cb : clipChromaIfNoBilat_Cr; - if(use_clip && currTU.blocks[compID].valid()) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(srcYuv, resYuv, cs.slice->clpRng(compID), currTU, isCb); - } - } + tuCBF = TU::getCbf(currTU, compID); } - } + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17)) && (tuValid)); + } + else + { + tuCBF = TU::getCbf(currTU, compID); + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17))); + } + if(applyChromaBIF) + { + m_bilateralFilter.bilateralFilterDiamond5x5Chroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); + } + else + { + bool useClip = isCb ? clipChromaIfNoBilatCb : clipChromaIfNoBilatCr; + if(useClip && currTU.blocks[compID].valid()) + { + m_bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(srcYuv, resYuv, cs.slice->clpRng(compID), currTU, isCb); + } + } + } } + } }// BIF chroma is disabled else { bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; + ChannelType chType = isDualTree ? CH_C : CH_L; - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) + { + continue; + } + for (auto &currTU : CU::traverseTUs(currCU)) + { + if(clipChromaIfNoBilatCb && currTU.blocks[COMPONENT_Cb].valid()) { - continue; + m_bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Cb), currTU, true); } - for (auto &currTU : CU::traverseTUs(currCU)) + if(clipChromaIfNoBilatCr && currTU.blocks[COMPONENT_Cr].valid()) { - if(clipChromaIfNoBilat_Cb && currTU.blocks[COMPONENT_Cb].valid()) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Cb), currTU, true); - } - if(clipChromaIfNoBilat_Cr && currTU.blocks[COMPONENT_Cr].valid()) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Cr), currTU, false); - } + m_bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Cr), currTU, false); } + } } - } + } #endif } else @@ -1618,104 +1615,101 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn } #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()) - { - offsetCTUnoClip(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); + if(cs.pps->getUseChromaBIF()) + { + offsetCTUnoClip(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); + SAOBlkParam mySAOblkParam = cs.picture->getSAO()[ctuRsAddr]; + SAOOffset& myCtbOffset = mySAOblkParam[0]; - SAOBlkParam mySAOblkParam = cs.picture->getSAO()[ctuRsAddr]; - SAOOffset& myCtbOffset = mySAOblkParam[0]; + bool clipLumaIfNoBilat = false; + if(myCtbOffset.modeIdc != SAO_MODE_OFF) + { + clipLumaIfNoBilat = true; + } - bool clipLumaIfNoBilat = false; - if(myCtbOffset.modeIdc != SAO_MODE_OFF) + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) + { + for (auto &currTU : CU::traverseTUs(currCU)) { - clipLumaIfNoBilat = true; + if(clipLumaIfNoBilat) + { + bilateralFilter.clipNotBilaterallyFilteredBlocks(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Y), currTU); + } } + } - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) - { - for (auto &currTU : CU::traverseTUs(currCU)) - { - if(clipLumaIfNoBilat) - bilateralFilter.clipNotBilaterallyFilteredBlocks(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Y), currTU); - } - } + SAOOffset& myCtbOffsetCb = mySAOblkParam[1]; + SAOOffset& myCtbOffsetCr = mySAOblkParam[2]; + bool clipChromaIfNoBilatCb = false; + bool clipChromaIfNoBilatCr = false; + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); - SAOOffset& myCtbOffset_Cb = mySAOblkParam[1]; - SAOOffset& myCtbOffset_Cr = mySAOblkParam[2]; - bool clipChromaIfNoBilat_Cb = false; - bool clipChromaIfNoBilat_Cr = false; - CBifParams& CBifParams = cs.picture->getCBifParam(); + if(myCtbOffsetCb.modeIdc != SAO_MODE_OFF) + { + clipChromaIfNoBilatCb = true; + } + if(myCtbOffsetCr.modeIdc != SAO_MODE_OFF) + { + clipChromaIfNoBilatCr = true; + } - if(myCtbOffset_Cb.modeIdc != SAO_MODE_OFF) - { - clipChromaIfNoBilat_Cb = true; - } - if(myCtbOffset_Cr.modeIdc != SAO_MODE_OFF) + bool tuValid = false; + bool tuCBF = false; + bool isDualTree = CS::isDualITree(cs); + ChannelType chType = isDualTree ? CH_C : CH_L; + bool applyChromaBIF = false; + + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) + { + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) { - clipChromaIfNoBilat_Cr = true; + continue; } - - bool TU_VALID = false; - bool TU_CBF = false; - bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - bool BIF_chroma = false; - - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + for (auto &currTU : CU::traverseTUs(currCU)) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) + { + bool isCb = compIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + bool ctuEnableChromaBIF = isCb ? chromaBifParams.ctuOnCb[ctuRsAddr] : chromaBifParams.ctuOnCr[ctuRsAddr]; + applyChromaBIF = false; + if(!isDualTree) { - continue; + tuValid = currTU.blocks[compIdx].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) + { + tuCBF = TU::getCbf(currTU, compID); + } + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17)) && (tuValid)); } - - for (auto &currTU : CU::traverseTUs(currCU)) + else { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - - for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) - { - bool isCb = compIdx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - bool CTU_ON = isCb ? CBifParams.ctuOn_Cb[ctuRsAddr] : CBifParams.ctuOn_Cr[ctuRsAddr]; - - BIF_chroma = false; - if(!isDualTree) - { - TU_VALID = currTU.blocks[compIdx].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero - if(TU_VALID) - { - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17)) && (TU_VALID)); - } - else - { - TU_CBF = TU::getCbf(currTU, compID); - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17))); - } - - if(BIF_chroma) - { - m_bilateralFilter.bilateralFilterDiamond5x5_chroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); - } - else - { - bool use_clip = isCb ? clipChromaIfNoBilat_Cb : clipChromaIfNoBilat_Cr; - if(use_clip && currTU.blocks[compID].valid()) - { - m_bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(srcYuv, resYuv, cs.slice->clpRng(compID), currTU, isCb); - } - } - } + tuCBF = TU::getCbf(currTU, compID); + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17))); + } + if(applyChromaBIF) + { + m_bilateralFilter.bilateralFilterDiamond5x5Chroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); + } + else + { + bool useClip = isCb ? clipChromaIfNoBilatCb : clipChromaIfNoBilatCr; + if(useClip && currTU.blocks[compID].valid()) + { + m_bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(srcYuv, resYuv, cs.slice->clpRng(compID), currTU, isCb); + } } + } } - } - else - { - offsetCTU(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); - } + } + } + else + { + offsetCTU(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); + } #else offsetCTU(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); #endif @@ -1736,13 +1730,13 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn //reconstruct #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (isGreedymergeEncoding || (cs.pps->getUseBIF() &&allBlksDisabled) || (cs.pps->getUseCBIF() &&allBlksDisabled)) + if (isGreedymergeEncoding || (cs.pps->getUseBIF() &&allBlksDisabled) || (cs.pps->getUseChromaBIF() &&allBlksDisabled)) #else if (isGreedymergeEncoding || (cs.pps->getUseBIF() &&allBlksDisabled) ) #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (isGreedymergeEncoding || (cs.pps->getUseCBIF() &&allBlksDisabled) ) + if (isGreedymergeEncoding || (cs.pps->getUseChromaBIF() &&allBlksDisabled) ) #else if (isGreedymergeEncoding) #endif @@ -1774,24 +1768,27 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn } #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()){ - for(int chroma_idx = COMPONENT_Cb; chroma_idx < MAX_NUM_COMPONENT; chroma_idx++){ - - bool isCb = chroma_idx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + if(cs.pps->getUseChromaBIF()) + { + for(int chromaIdx = COMPONENT_Cb; chromaIdx < MAX_NUM_COMPONENT; chromaIdx++) + { + bool isCb = chromaIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - int myResStride_chroma = resYuv.get(compID).stride; - const CompArea& myCompArea_chroma = area.block(compID); - Pel* myResBlk_chroma = resYuv.get(compID).bufAt(myCompArea_chroma); - int mySrcStride_chroma = srcYuv.get(compID).stride; - Pel* mySrcBlk_chroma = srcYuv.get(compID).bufAt(myCompArea_chroma); + int myResStrideChroma = resYuv.get(compID).stride; + const CompArea& myCompAreaChroma = area.block(compID); + Pel* myResBlkChroma = resYuv.get(compID).bufAt(myCompAreaChroma); + int mySrcStrideChroma = srcYuv.get(compID).stride; + Pel* mySrcBlkChroma = srcYuv.get(compID).bufAt(myCompAreaChroma); - for(int yy = 0; yy<area.chromaSize().height; yy++){ - for(int xx = 0; xx<area.chromaSize().width; xx++){ - myResBlk_chroma[yy*myResStride_chroma+xx] = mySrcBlk_chroma[yy*mySrcStride_chroma+xx]; - } - } + for(int yy = 0; yy<area.chromaSize().height; yy++) + { + for(int xx = 0; xx<area.chromaSize().width; xx++) + { + myResBlkChroma[yy*myResStrideChroma+xx] = mySrcBlkChroma[yy*mySrcStrideChroma+xx]; + } } + } } #endif @@ -1816,207 +1813,206 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn } #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { - CBifParams& CBifParams = cs.picture->getCBifParam(); - bool TU_VALID = false; - bool TU_CBF = false; - bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - bool BIF_chroma = false; + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); + bool tuValid = false; + bool tuCBF = false; + bool isDualTree = CS::isDualITree(cs); + ChannelType chType = isDualTree ? CH_C : CH_L; + bool applyChromaBIF = false; + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) + { + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) + { + continue; + } - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + for (auto &currTU : CU::traverseTUs(currCU)) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) + { + bool isCb = compIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + bool ctuEnableChromaBIF = isCb ? chromaBifParams.ctuOnCb[ctuRsAddr] : chromaBifParams.ctuOnCr[ctuRsAddr]; + + applyChromaBIF = false; + if(!isDualTree) { - continue; + tuValid = currTU.blocks[compIdx].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) + { + tuCBF = TU::getCbf(currTU, compID); + } + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17)) && (tuValid)); } - - for (auto &currTU : CU::traverseTUs(currCU)) + else { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - - for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) - { - bool isCb = compIdx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - bool CTU_ON = isCb ? CBifParams.ctuOn_Cb[ctuRsAddr] : CBifParams.ctuOn_Cr[ctuRsAddr]; - - BIF_chroma = false; - if(!isDualTree) - { - TU_VALID = currTU.blocks[compIdx].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero - - if(TU_VALID) - { - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17)) && (TU_VALID)); - } - else - { - TU_CBF = TU::getCbf(currTU, compID); - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17))); - } - if(BIF_chroma) - { - bilateralFilter.bilateralFilterDiamond5x5NoClip_chroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); - } - } + tuCBF = TU::getCbf(currTU, compID); + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17))); } + if(applyChromaBIF) + { + bilateralFilter.bilateralFilterDiamond5x5NoClipChroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); + } + } } + } } #endif #else #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseBIF() || cs.pps->getUseCBIF()) + if(cs.pps->getUseBIF() || cs.pps->getUseChromaBIF()) { - offsetCTUnoClip(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); - SAOBlkParam mySAOblkParam = cs.picture->getSAO()[ctuRsAddr]; - SAOOffset& myCtbOffset = mySAOblkParam[0]; - BifParams& bifParams = cs.picture->getBifParam(); + offsetCTUnoClip(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); + SAOBlkParam mySAOblkParam = cs.picture->getSAO()[ctuRsAddr]; + SAOOffset& myCtbOffset = mySAOblkParam[0]; + BifParams& bifParams = cs.picture->getBifParam(); - bool clipLumaIfNoBilat = false; - if(myCtbOffset.modeIdc != SAO_MODE_OFF) - clipLumaIfNoBilat = true; + bool clipLumaIfNoBilat = false; + if(myCtbOffset.modeIdc != SAO_MODE_OFF) + { + clipLumaIfNoBilat = true; + } - CBifParams& CBifParams = cs.picture->getCBifParam(); - SAOOffset& myCtbOffset_Cb = mySAOblkParam[1]; - SAOOffset& myCtbOffset_Cr = mySAOblkParam[2]; - bool clipChromaIfNoBilat_Cb = false; - bool clipChromaIfNoBilat_Cr = false; + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); + SAOOffset& myCtbOffsetCb = mySAOblkParam[1]; + SAOOffset& myCtbOffsetCr = mySAOblkParam[2]; + bool clipChromaIfNoBilatCb = false; + bool clipChromaIfNoBilatCr = false; - if(myCtbOffset_Cb.modeIdc != SAO_MODE_OFF) - { - clipChromaIfNoBilat_Cb = true; - } - if(myCtbOffset_Cr.modeIdc != SAO_MODE_OFF) - { - clipChromaIfNoBilat_Cr = true; - } - if(cs.pps->getUseBIF()) + if(myCtbOffsetCb.modeIdc != SAO_MODE_OFF) + { + clipChromaIfNoBilatCb = true; + } + if(myCtbOffsetCr.modeIdc != SAO_MODE_OFF) + { + clipChromaIfNoBilatCr = true; + } + if(cs.pps->getUseBIF()) + { + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) { - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) + for (auto &currTU : CU::traverseTUs(currCU)) + { + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + if ( bifParams.ctuOn[ctuRsAddr] && ((TU::getCbf(currTU, COMPONENT_Y) || isInter == false) && (currTU.cu->qp > 17)) && (128 > std::max(currTU.lumaSize().width, currTU.lumaSize().height)) && ((isInter == false) || (32 > std::min(currTU.lumaSize().width, currTU.lumaSize().height)))) { - for (auto &currTU : CU::traverseTUs(currCU)) - { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - if ( bifParams.ctuOn[ctuRsAddr] && ((TU::getCbf(currTU, COMPONENT_Y) || isInter == false) && (currTU.cu->qp > 17)) && (128 > std::max(currTU.lumaSize().width, currTU.lumaSize().height)) && ((isInter == false) || (32 > std::min(currTU.lumaSize().width, currTU.lumaSize().height)))) - { - bilateralFilter.bilateralFilterDiamond5x5(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(COMPONENT_Y), currTU); - } - else - { - // We don't need to clip if SAO was not performed on luma. - if(clipLumaIfNoBilat) - bilateralFilter.clipNotBilaterallyFilteredBlocks(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Y), currTU); - } - } + bilateralFilter.bilateralFilterDiamond5x5(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(COMPONENT_Y), currTU); } + else + { + // We don't need to clip if SAO was not performed on luma. + if(clipLumaIfNoBilat) + { + bilateralFilter.clipNotBilaterallyFilteredBlocks(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Y), currTU); + } + } + } } - else + } + else + { + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) { - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) + for (auto &currTU : CU::traverseTUs(currCU)) + { + if(clipLumaIfNoBilat) { - for (auto &currTU : CU::traverseTUs(currCU)) - { - if(clipLumaIfNoBilat) - bilateralFilter.clipNotBilaterallyFilteredBlocks(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Y), currTU); - } + bilateralFilter.clipNotBilaterallyFilteredBlocks(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Y), currTU); } + } } + } - if(cs.pps->getUseCBIF()) - { - bool TU_VALID = false; - bool TU_CBF = false; - bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - bool BIF_chroma = false; + if(cs.pps->getUseChromaBIF()) + { + bool tuValid = false; + bool tuCBF = false; + bool isDualTree = CS::isDualITree(cs); + ChannelType chType = isDualTree ? CH_C : CH_L; + bool applyChromaBIF = false; - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) + { + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) + { + continue; + } + for (auto &currTU : CU::traverseTUs(currCU)) + { + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) + bool isCb = compIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + bool ctuEnableChromaBIF = isCb ? chromaBifParams.ctuOnCb[ctuRsAddr] : chromaBifParams.ctuOnCr[ctuRsAddr]; + applyChromaBIF = false; + if(!isDualTree) + { + tuValid = currTU.blocks[compIdx].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) { - continue; + tuCBF = TU::getCbf(currTU, compID); } - for (auto &currTU : CU::traverseTUs(currCU)) + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17)) && (tuValid)); + } + else + { + tuCBF = TU::getCbf(currTU, compID); + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17))); + } + if(applyChromaBIF) + { + bilateralFilter.bilateralFilterDiamond5x5Chroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); + } + else + { + bool useClip = isCb ? clipChromaIfNoBilatCb : clipChromaIfNoBilatCr; + if(useClip && currTU.blocks[compIdx].valid()) { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - - for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) - { - bool isCb = compIdx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - bool CTU_ON = isCb ? CBifParams.ctuOn_Cb[ctuRsAddr] : CBifParams.ctuOn_Cr[ctuRsAddr]; - - BIF_chroma = false; - if(!isDualTree) - { - TU_VALID = currTU.blocks[compIdx].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero - - if(TU_VALID) - { - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17)) && (TU_VALID)); - } - else - { - TU_CBF = TU::getCbf(currTU, compID); - BIF_chroma = (CTU_ON && (( TU_CBF || isInter == false) && (currTU.cu->qp > 17))); - } - if(BIF_chroma) - { - bilateralFilter.bilateralFilterDiamond5x5_chroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); - } - else - { - bool use_clip = isCb ? clipChromaIfNoBilat_Cb : clipChromaIfNoBilat_Cr; - if(use_clip && currTU.blocks[compIdx].valid()) - { - bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(srcYuv, resYuv, cs.slice->clpRng(compID), currTU, isCb); - } - } - } + bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(srcYuv, resYuv, cs.slice->clpRng(compID), currTU, isCb); } + } } + } } - else - { - bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; + } + else + { + bool isDualTree = CS::isDualITree(cs); + ChannelType chType = isDualTree ? CH_C : CH_L; - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) + { + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) + { + continue; + } + for (auto &currTU : CU::traverseTUs(currCU)) + { + if(clipChromaIfNoBilatCb && currTU.blocks[COMPONENT_Cb].valid()) { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) - { - continue; - } - - for (auto &currTU : CU::traverseTUs(currCU)) - { - if(clipChromaIfNoBilat_Cb && currTU.blocks[COMPONENT_Cb].valid()) - { - bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Cb), currTU, true); - } - if(clipChromaIfNoBilat_Cr && currTU.blocks[COMPONENT_Cr].valid()) - { - bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Cr), currTU, false); - } - } + bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Cb), currTU, true); + } + if(clipChromaIfNoBilatCr && currTU.blocks[COMPONENT_Cr].valid()) + { + bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Cr), currTU, false); } + } } + } }//BIF = 1 OR CBIF = 1 else { - offsetCTU(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); + offsetCTU(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); } #else if(cs.pps->getUseBIF()) @@ -2063,103 +2059,100 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(cs.pps->getUseCBIF()) + if(cs.pps->getUseChromaBIF()) { - offsetCTUnoClip(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); + offsetCTUnoClip(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); - SAOBlkParam mySAOblkParam = cs.picture->getSAO()[ctuRsAddr]; - CBifParams& CBifParams = cs.picture->getCBifParam(); + SAOBlkParam mySAOblkParam = cs.picture->getSAO()[ctuRsAddr]; + ChromaBifParams& chromaBifParams = cs.picture->getChromaBifParam(); - SAOOffset& myCtbOffset = mySAOblkParam[0]; - bool clipLumaIfNoBilat = false; - if(myCtbOffset.modeIdc != SAO_MODE_OFF) - { - clipLumaIfNoBilat = true; - } + SAOOffset& myCtbOffset = mySAOblkParam[0]; + bool clipLumaIfNoBilat = false; + if(myCtbOffset.modeIdc != SAO_MODE_OFF) + { + clipLumaIfNoBilat = true; + } + + SAOOffset& myCtbOffsetCb = mySAOblkParam[1]; + SAOOffset& myCtbOffsetCr = mySAOblkParam[2]; + bool clipChromaIfNoBilatCb = false; + bool clipChromaIfNoBilatCr = false; - SAOOffset& myCtbOffset_Cb = mySAOblkParam[1]; - SAOOffset& myCtbOffset_Cr = mySAOblkParam[2]; - bool clipChromaIfNoBilat_Cb = false; - bool clipChromaIfNoBilat_Cr = false; + if(myCtbOffsetCb.modeIdc != SAO_MODE_OFF) + { + clipChromaIfNoBilatCb = true; + } + if(myCtbOffsetCr.modeIdc != SAO_MODE_OFF) + { + clipChromaIfNoBilatCr = true; + } - if(myCtbOffset_Cb.modeIdc != SAO_MODE_OFF) + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) + { + for (auto &currTU : CU::traverseTUs(currCU)) { - clipChromaIfNoBilat_Cb = true; + if(clipLumaIfNoBilat) + { + bilateralFilter.clipNotBilaterallyFilteredBlocks(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Y), currTU); + } } - if(myCtbOffset_Cr.modeIdc != SAO_MODE_OFF) + } + + bool tuValid = false; + bool tuCBF = false; + bool isDualTree = CS::isDualITree(cs); + ChannelType chType = isDualTree ? CH_C : CH_L; + bool applyChromaBIF = false; + for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, chType), chType)) + { + bool chromaValid = currCU.Cb().valid() && currCU.Cr().valid(); + if(!chromaValid) { - clipChromaIfNoBilat_Cr = true; + continue; } - - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CH_L), CH_L)) + for (auto &currTU : CU::traverseTUs(currCU)) { - for (auto &currTU : CU::traverseTUs(currCU)) + bool isInter = (currCU.predMode == MODE_INTER) ? true : false; + for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) + { + bool isCb = compIdx == COMPONENT_Cb ? true : false; + ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; + bool ctuEnableChromaBIF = isCb ? chromaBifParams.ctuOnCb[ctuRsAddr] : chromaBifParams.ctuOnCr[ctuRsAddr]; + applyChromaBIF = false; + if(!isDualTree) { - if(clipLumaIfNoBilat) - { - bilateralFilter.clipNotBilaterallyFilteredBlocks(srcYuv, resYuv, cs.slice->clpRng(COMPONENT_Y), currTU); - } + tuValid = currTU.blocks[compIdx].valid(); + tuCBF = false;//if CHROMA TU is not vaild, CBF must be zero + if(tuValid) + { + tuCBF = TU::getCbf(currTU, compID); + } + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17)) && (tuValid)); } - } - - bool TU_VALID = false; - bool TU_CBF = false; - bool isDualTree = CS::isDualITree(cs); - ChannelType CType = isDualTree ? CH_C : CH_L; - bool BIF_chroma = false; - - for (auto &currCU : cs.traverseCUs(CS::getArea(cs, area, CType), CType)) - { - bool chroma_valid = currCU.Cb().valid() && currCU.Cr().valid(); - if(!chroma_valid) + else { - continue; + tuCBF = TU::getCbf(currTU, compID); + applyChromaBIF = (ctuEnableChromaBIF && ((tuCBF || isInter == false) && (currTU.cu->qp > 17))); } - for (auto &currTU : CU::traverseTUs(currCU)) + if(applyChromaBIF) { - bool isInter = (currCU.predMode == MODE_INTER) ? true : false; - - for(int compIdx = COMPONENT_Cb; compIdx < MAX_NUM_COMPONENT; compIdx++) - { - bool isCb = compIdx == COMPONENT_Cb ? true : false; - ComponentID compID = isCb ? COMPONENT_Cb : COMPONENT_Cr; - bool CTU_ON = isCb ? CBifParams.ctuOn_Cb[ctuRsAddr] : CBifParams.ctuOn_Cr[ctuRsAddr]; - - BIF_chroma = false; - if(!isDualTree) - { - TU_VALID = currTU.blocks[compIdx].valid(); - TU_CBF = false;//if CHROMA TU is not vaild, CBF must be zero - if(TU_VALID) - { - TU_CBF = TU::getCbf(currTU, compID); - } - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17)) && (TU_VALID)); - } - else - { - TU_CBF = TU::getCbf(currTU, compID); - BIF_chroma = (CTU_ON && ((TU_CBF || isInter == false) && (currTU.cu->qp > 17))); - } - if(BIF_chroma) - { - bilateralFilter.bilateralFilterDiamond5x5_chroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); - } - else - { - bool use_clip = isCb ? clipChromaIfNoBilat_Cb : clipChromaIfNoBilat_Cr; - if(use_clip && currTU.blocks[compIdx].valid()) - { - bilateralFilter.clipNotBilaterallyFilteredBlocks_chroma(srcYuv, resYuv, cs.slice->clpRng(compID), currTU, isCb); - } - } - } + bilateralFilter.bilateralFilterDiamond5x5Chroma(srcYuv, resYuv, currTU.cu->qp, cs.slice->clpRng(compID), currTU, isCb); } + else + { + bool useClip = isCb ? clipChromaIfNoBilatCb : clipChromaIfNoBilatCr; + if(useClip && currTU.blocks[compIdx].valid()) + { + bilateralFilter.clipNotBilaterallyFilteredBlocksChroma(srcYuv, resYuv, cs.slice->clpRng(compID), currTU, isCb); + } + } + } } + } } else { - offsetCTU(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); + offsetCTU(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); } #else offsetCTU(area, srcYuv, resYuv, reconParams[ctuRsAddr], cs); @@ -2172,7 +2165,7 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn //delete memory #if JVET_V0094_BILATERAL_FILTER #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(!(cs.pps->getUseBIF()) || !(cs.pps->getUseCBIF()) || !allBlksDisabled) + if(!(cs.pps->getUseBIF()) || !(cs.pps->getUseChromaBIF()) || !allBlksDisabled) { #else if (!(cs.pps->getUseBIF()) || !allBlksDisabled) @@ -2180,7 +2173,7 @@ void EncSampleAdaptiveOffset::decideBlkParams(CodingStructure& cs, bool* sliceEn #endif #else #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (!(cs.pps->getUseCBIF()) || !allBlksDisabled) + if (!(cs.pps->getUseChromaBIF()) || !allBlksDisabled) { #else // DO NOTHING diff --git a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h index 3ebfb14c0d5343a580393636fd124df1747e0293..1456613b7d475fea800607d1d0874782474663c6 100644 --- a/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h +++ b/source/Lib/EncoderLib/EncSampleAdaptiveOffset.h @@ -161,7 +161,7 @@ public: ,BIFCabacEst* BifCABACEstimator #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - ,CBIFCabacEst* CBifCABACEstimator + ,ChromaBIFCabacEst* ChromaBifCABACEstimator #endif ); #if JVET_W0066_CCSAO diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index 13cb93d761e86bd12d34294ce360ace2f26a35cb..0a5240596c2e88d3aeeaa0c5af07524ea2d68ec8 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -1736,7 +1736,7 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons resetBcwCodingOrder(false, cs); m_pcInterSearch->initWeightIdxBits(); } -#if !JVET_V0094_BILATERAL_FILTER +#if !JVET_V0094_BILATERAL_FILTER && !JVET_X0071_CHROMA_BILATERAL_FILTER if (pcSlice->getSPS()->getUseLmcs()) #endif { @@ -1943,9 +1943,9 @@ void EncSlice::encodeSlice ( Picture* pcPic, OutputBitstream* pcSubstreams, ui #if JVET_X0071_CHROMA_BILATERAL_FILTER if(ctuRsAddr == 0) { - CBifParams& CBifParam = cs.picture->getCBifParam(); - m_CABACWriter->Cbif_Cb(*pcSlice, CBifParam); - m_CABACWriter->Cbif_Cr(*pcSlice, CBifParam); + ChromaBifParams& chromaBifParam = cs.picture->getChromaBifParam(); + m_CABACWriter->chromaBifCb(*pcSlice, chromaBifParam); + m_CABACWriter->chromaBifCr(*pcSlice, chromaBifParam); } #endif m_CABACWriter->coding_tree_unit( cs, ctuArea, pcPic->m_prevQP, ctuRsAddr ); diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp index 03fa0d3d19e39a7389f4b8ddf36fa7ea65a8300d..06eb308dd04d158d92694cf78e042ac43d01ef12 100644 --- a/source/Lib/EncoderLib/InterSearch.cpp +++ b/source/Lib/EncoderLib/InterSearch.cpp @@ -7999,24 +7999,22 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par #if JVET_X0071_CHROMA_BILATERAL_FILTER if(isChroma(compID)) { - if (cs.pps->getUseCBIF() && isChroma(compID) && (tu.cu->qp > 17)) + if (cs.pps->getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17)) { - //chroma and bilateral - CompArea tmpArea1(compID, tu.chromaFormat, Position(0, 0), Size(resiBuf.width, resiBuf.height)); - PelBuf tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea1); - tmpRecChroma.copyFrom(resiBuf); - - const CPelBuf predBuf = csFull->getPredBuf(compArea); - PelBuf recIPredBuf = csFull->slice->getPic()->getRecoBuf(compArea); - bool isCb = compID == COMPONENT_Cb ? true : false; - - m_bilateralFilter->bilateralFilterRDOdiamond5x5_chroma(tmpRecChroma, predBuf, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, false, isCb); - - currCompDist = m_pcRdCost->getDistPart(orgResiBuf, tmpRecChroma, channelBitDepth, compID, DF_SSE); + //chroma and bilateral + CompArea tmpArea1(compID, tu.chromaFormat, Position(0, 0), Size(resiBuf.width, resiBuf.height)); + PelBuf tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea1); + tmpRecChroma.copyFrom(resiBuf); + + const CPelBuf predBuf = csFull->getPredBuf(compArea); + PelBuf recIPredBuf = csFull->slice->getPic()->getRecoBuf(compArea); + bool isCb = compID == COMPONENT_Cb ? true : false; + m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, predBuf, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, false, isCb); + currCompDist = m_pcRdCost->getDistPart(orgResiBuf, tmpRecChroma, channelBitDepth, compID, DF_SSE); } else { //chroma but not bilateral - currCompDist = m_pcRdCost->getDistPart(orgResiBuf, resiBuf, channelBitDepth, compID, DF_SSE); + currCompDist = m_pcRdCost->getDistPart(orgResiBuf, resiBuf, channelBitDepth, compID, DF_SSE); } } else @@ -8031,26 +8029,28 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par #if JVET_X0071_CHROMA_BILATERAL_FILTER if(isChroma(compID)) { - if(cs.pps->getUseCBIF() && isChroma(compID) && (tu.cu->qp > 17)){ - //chroma and bilateral - CompArea tmpArea1(compID, tu.chromaFormat, Position(0, 0), Size(resiBuf.width, resiBuf.height)); - PelBuf tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea1); - tmpRecChroma.copyFrom(resiBuf); - - const CPelBuf predBuf = csFull->getPredBuf(compArea); - PelBuf recIPredBuf = csFull->slice->getPic()->getRecoBuf(compArea); - bool isCb = compID == COMPONENT_Cb ? true : false; - - m_bilateralFilter->bilateralFilterRDOdiamond5x5_chroma(tmpRecChroma, predBuf, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, false, isCb); - - currCompDist = m_pcRdCost->getDistPart(orgResiBuf, tmpRecChroma, channelBitDepth, compID, DF_SSE); - } - else{//chroma but not bilateral - currCompDist = m_pcRdCost->getDistPart(orgResiBuf, resiBuf, channelBitDepth, compID, DF_SSE); - } - } - else{//luma but not bilateral + if(cs.pps->getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17)) + { + //chroma and bilateral + CompArea tmpArea1(compID, tu.chromaFormat, Position(0, 0), Size(resiBuf.width, resiBuf.height)); + PelBuf tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea1); + tmpRecChroma.copyFrom(resiBuf); + const CPelBuf predBuf = csFull->getPredBuf(compArea); + PelBuf recIPredBuf = csFull->slice->getPic()->getRecoBuf(compArea); + bool isCb = compID == COMPONENT_Cb ? true : false; + m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, predBuf, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, false, isCb); + currCompDist = m_pcRdCost->getDistPart(orgResiBuf, tmpRecChroma, channelBitDepth, compID, DF_SSE); + } + else + { + //chroma but not bilateral currCompDist = m_pcRdCost->getDistPart(orgResiBuf, resiBuf, channelBitDepth, compID, DF_SSE); + } + } + else + { + //luma but not bilateral + currCompDist = m_pcRdCost->getDistPart(orgResiBuf, resiBuf, channelBitDepth, compID, DF_SSE); } #else currCompDist = m_pcRdCost->getDistPart(orgResiBuf, resiBuf, channelBitDepth, compID, DF_SSE); @@ -9060,30 +9060,29 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa } #if JVET_X0071_CHROMA_BILATERAL_FILTER PelBuf tmpRecChroma; - if(isChroma(compID)){ - - bool isCb = compID == COMPONENT_Cb ? true : false; - const CompArea &areaUV = isCb ? cu.Cb() : cu.Cr(); - CompArea tmpArea2(isCb ? COMPONENT_Cb : COMPONENT_Cr, areaUV.chromaFormat, Position(0, 0), areaUV.size()); - tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea2); - tmpRecChroma.copyFrom(reco); + if(isChroma(compID)) + { + bool isCb = compID == COMPONENT_Cb ? true : false; + const CompArea &areaUV = isCb ? cu.Cb() : cu.Cr(); + CompArea tmpArea2(isCb ? COMPONENT_Cb : COMPONENT_Cr, areaUV.chromaFormat, Position(0, 0), areaUV.size()); + tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea2); + tmpRecChroma.copyFrom(reco); - if(cs.pps->getUseCBIF() && isChroma(compID) && (cu.qp > 17)) + if(cs.pps->getUseChromaBIF() && isChroma(compID) && (cu.qp > 17)) + { + for (auto &currTU : CU::traverseTUs(cu)) { - for (auto &currTU : CU::traverseTUs(cu)) - { - Position tuPosInCu = currTU.chromaPos() - cu.chromaPos(); - PelBuf tmpSubBuf = tmpRecChroma.subBuf(tuPosInCu, currTU.chromaSize()); - bool isInter = (cu.predMode == MODE_INTER) ? true : false; - - if ((TU::getCbf(currTU, isCb ? COMPONENT_Cb : COMPONENT_Cr) || isInter == false)) - { - CompArea compArea = currTU.blocks[compID]; - PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea); - m_bilateralFilter->bilateralFilterRDOdiamond5x5_chroma(tmpSubBuf, tmpSubBuf, tmpSubBuf, currTU.cu->qp, recIPredBuf, cs.slice->clpRng(compID), currTU, true, isCb); - } - } + Position tuPosInCu = currTU.chromaPos() - cu.chromaPos(); + PelBuf tmpSubBuf = tmpRecChroma.subBuf(tuPosInCu, currTU.chromaSize()); + bool isInter = (cu.predMode == MODE_INTER) ? true : false; + if ((TU::getCbf(currTU, isCb ? COMPONENT_Cb : COMPONENT_Cr) || isInter == false)) + { + CompArea compArea = currTU.blocks[compID]; + PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea); + m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpSubBuf, tmpSubBuf, tmpSubBuf, currTU.cu->qp, recIPredBuf, cs.slice->clpRng(compID), currTU, true, isCb); + } } + } } #endif #if WCG_EXT @@ -9102,7 +9101,7 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa else #if JVET_X0071_CHROMA_BILATERAL_FILTER { - finalDistortion += m_pcRdCost->getDistPart(org, tmpRecChroma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma); + finalDistortion += m_pcRdCost->getDistPart(org, tmpRecChroma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma); } #else finalDistortion += m_pcRdCost->getDistPart(org, reco, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma); @@ -9129,29 +9128,26 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa PelBuf tmpRecChroma; if(isChroma(compID)) { - bool isCb = compID == COMPONENT_Cb ? true : false; - const CompArea &areaUV = isCb ? cu.Cb() : cu.Cr(); - CompArea tmpArea2(isCb ? COMPONENT_Cb : COMPONENT_Cr, areaUV.chromaFormat, Position(0, 0), areaUV.size()); - tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea2); - tmpRecChroma.copyFrom(reco); - - if(cs.pps->getUseCBIF() && isChroma(compID) && (cu.qp > 17)) + bool isCb = compID == COMPONENT_Cb ? true : false; + const CompArea &areaUV = isCb ? cu.Cb() : cu.Cr(); + CompArea tmpArea2(isCb ? COMPONENT_Cb : COMPONENT_Cr, areaUV.chromaFormat, Position(0, 0), areaUV.size()); + tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea2); + tmpRecChroma.copyFrom(reco); + if(cs.pps->getUseChromaBIF() && isChroma(compID) && (cu.qp > 17)) + { + for (auto &currTU : CU::traverseTUs(cu)) { - - for (auto &currTU : CU::traverseTUs(cu)) - { - Position tuPosInCu = currTU.chromaPos() - cu.chromaPos(); - PelBuf tmpSubBuf = tmpRecChroma.subBuf(tuPosInCu, currTU.chromaSize()); - bool isInter = (cu.predMode == MODE_INTER) ? true : false; - - if ((TU::getCbf(currTU, isCb ? COMPONENT_Cb : COMPONENT_Cr) || isInter == false)) - { - CompArea compArea = currTU.blocks[compID]; - PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea); - m_bilateralFilter->bilateralFilterRDOdiamond5x5_chroma(tmpSubBuf, tmpSubBuf, tmpSubBuf, currTU.cu->qp, recIPredBuf, cs.slice->clpRng(compID), currTU, true, isCb); - } - } + Position tuPosInCu = currTU.chromaPos() - cu.chromaPos(); + PelBuf tmpSubBuf = tmpRecChroma.subBuf(tuPosInCu, currTU.chromaSize()); + bool isInter = (cu.predMode == MODE_INTER) ? true : false; + if ((TU::getCbf(currTU, isCb ? COMPONENT_Cb : COMPONENT_Cr) || isInter == false)) + { + CompArea compArea = currTU.blocks[compID]; + PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea); + m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpSubBuf, tmpSubBuf, tmpSubBuf, currTU.cu->qp, recIPredBuf, cs.slice->clpRng(compID), currTU, true, isCb); + } } + } } #endif #if WCG_EXT @@ -9169,12 +9165,14 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa else { #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(isChroma(compID)){ - finalDistortion += m_pcRdCost->getDistPart(org, tmpRecChroma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma); - } - else{ - finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma ); - } + if(isChroma(compID)) + { + finalDistortion += m_pcRdCost->getDistPart(org, tmpRecChroma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma); + } + else + { + finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma ); + } #else finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma ); #endif @@ -9184,7 +9182,8 @@ void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &pa #endif { #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(isChroma(compID)){ + if(isChroma(compID)) + { finalDistortion += m_pcRdCost->getDistPart( org, tmpRecChroma, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE ); } else diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp index 069c00c463e98551be87053a264af4c79089b902..4112d72d053c3793d578c18a6f657e082626e3ce 100644 --- a/source/Lib/EncoderLib/IntraSearch.cpp +++ b/source/Lib/EncoderLib/IntraSearch.cpp @@ -3989,12 +3989,12 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp else { #if JVET_X0071_CHROMA_BILATERAL_FILTER - if(pps.getUseCBIF() && isChroma(compID) && (tu.cu->qp > 17)) + if(pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17)) { CompArea compArea = tu.blocks[compID]; PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea); bool isCb = compID == COMPONENT_Cb ? true : false; - m_bilateralFilter->bilateralFilterRDOdiamond5x5_chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb); + m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb); } ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecChroma, bitDepth, compID, DF_SSE_WTD, &orgLuma); #else @@ -4005,11 +4005,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp #if JVET_X0071_CHROMA_BILATERAL_FILTER if(compID == COMPONENT_Cr) { - ruiDist += m_pcRdCost->getDistPart(crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma); + ruiDist += m_pcRdCost->getDistPart(crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma); } else { - ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma); + ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma); } #else ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma); @@ -4035,12 +4035,12 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp else { #if JVET_X0071_CHROMA_BILATERAL_FILTER - if (pps.getUseCBIF() && isChroma(compID) && (tu.cu->qp > 17)) + if (pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17)) { CompArea compArea = tu.blocks[compID]; PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea); bool isCb = compID == COMPONENT_Cb ? true : false; - m_bilateralFilter->bilateralFilterRDOdiamond5x5_chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb); + m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb); } ruiDist += m_pcRdCost->getDistPart( piOrg, tmpRecChroma, bitDepth, compID, DF_SSE ); #else @@ -4051,10 +4051,11 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp #if JVET_X0071_CHROMA_BILATERAL_FILTER if(compID == COMPONENT_Cr) { - ruiDist += m_pcRdCost->getDistPart( crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE ); + ruiDist += m_pcRdCost->getDistPart( crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE ); } - else{ - ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE ); + else + { + ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE ); } #else ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE ); @@ -4070,82 +4071,83 @@ void IntraSearch::xIntraCodingTUBlock(TransformUnit &tu, const ComponentID &comp PelBuf tmpRecChroma; if(isChroma(compID)) { - tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea2); - tmpRecChroma.copyFrom(piReco); + tmpRecChroma = m_tmpStorageLCU.getBuf(tmpArea2); + tmpRecChroma.copyFrom(piReco); } #if WCG_EXT if (m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() || (m_pcEncCfg->getLmcs() && slice.getLmcsEnabledFlag() && (m_pcReshape->getCTUFlag() || (isChroma(compID) && m_pcEncCfg->getReshapeIntraCMD())))) { - const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] ); - if(isLuma(compID)) + const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] ); + if(isLuma(compID)) + { + if (compID == COMPONENT_Y && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled())) { - if (compID == COMPONENT_Y && !(m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled())) - { - CompArea tmpArea1(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size()); - PelBuf tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1); - tmpRecLuma.rspSignal( piReco, m_pcReshape->getInvLUT() ); - ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma); - } - else - { - ruiDist += m_pcRdCost->getDistPart(piOrg, piReco, bitDepth, compID, DF_SSE_WTD, &orgLuma); - if( jointCbCr ) - { - ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma); - } - } + CompArea tmpArea1(COMPONENT_Y, area.chromaFormat, Position(0, 0), area.size()); + PelBuf tmpRecLuma = m_tmpStorageLCU.getBuf(tmpArea1); + tmpRecLuma.rspSignal( piReco, m_pcReshape->getInvLUT() ); + ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecLuma, sps.getBitDepth(toChannelType(compID)), compID, DF_SSE_WTD, &orgLuma); } else { - if(pps.getUseCBIF() && isChroma(compID) && (tu.cu->qp > 17)) - { - CompArea compArea = tu.blocks[compID]; - PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea); - bool isCb = compID == COMPONENT_Cb ? true : false; - m_bilateralFilter->bilateralFilterRDOdiamond5x5_chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb); - } - ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecChroma, bitDepth, compID, DF_SSE_WTD, &orgLuma); - - if( jointCbCr ) - { - if(compID == COMPONENT_Cr) - { - ruiDist += m_pcRdCost->getDistPart(crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma); - } - else - { - ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma); - } - } + ruiDist += m_pcRdCost->getDistPart(piOrg, piReco, bitDepth, compID, DF_SSE_WTD, &orgLuma); + if( jointCbCr ) + { + ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma); + } + } + } + else + { + if(pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17)) + { + CompArea compArea = tu.blocks[compID]; + PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea); + bool isCb = compID == COMPONENT_Cb ? true : false; + m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb); } + ruiDist += m_pcRdCost->getDistPart(piOrg, tmpRecChroma, bitDepth, compID, DF_SSE_WTD, &orgLuma); + if( jointCbCr ) + { + if(compID == COMPONENT_Cr) + { + ruiDist += m_pcRdCost->getDistPart(crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma); + } + else + { + ruiDist += m_pcRdCost->getDistPart(crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE_WTD, &orgLuma); + } + } + } } else #endif { - if(isLuma(compID)) + if(isLuma(compID)) + { + ruiDist += m_pcRdCost->getDistPart( piOrg, piReco, bitDepth, compID, DF_SSE ); + } + else + { + if (pps.getUseChromaBIF() && isChroma(compID) && (tu.cu->qp > 17)) { - ruiDist += m_pcRdCost->getDistPart( piOrg, piReco, bitDepth, compID, DF_SSE ); + CompArea compArea = tu.blocks[compID]; + PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea); + bool isCb = compID == COMPONENT_Cb ? true : false; + m_bilateralFilter->bilateralFilterRDOdiamond5x5Chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb); } - else{ - if (pps.getUseCBIF() && isChroma(compID) && (tu.cu->qp > 17)) - { - CompArea compArea = tu.blocks[compID]; - PelBuf recIPredBuf = cs.slice->getPic()->getRecoBuf(compArea); - bool isCb = compID == COMPONENT_Cb ? true : false; - m_bilateralFilter->bilateralFilterRDOdiamond5x5_chroma(tmpRecChroma, tmpRecChroma, tmpRecChroma, tu.cu->qp, recIPredBuf, cs.slice->clpRng(compID), tu, true, isCb); - } - ruiDist += m_pcRdCost->getDistPart( piOrg, tmpRecChroma, bitDepth, compID, DF_SSE ); + ruiDist += m_pcRdCost->getDistPart( piOrg, tmpRecChroma, bitDepth, compID, DF_SSE ); + } + if( jointCbCr ) + { + if(compID == COMPONENT_Cr) + { + ruiDist += m_pcRdCost->getDistPart( crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE ); } - if( jointCbCr ) + else { - if(compID == COMPONENT_Cr) - { - ruiDist += m_pcRdCost->getDistPart( crOrg, tmpRecChroma, bitDepth, COMPONENT_Cr, DF_SSE ); - } - else{ - ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE ); - } + ruiDist += m_pcRdCost->getDistPart( crOrg, crReco, bitDepth, COMPONENT_Cr, DF_SSE ); } + } } #else #if WCG_EXT diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 971f7a05ad109efda2bc49d166a50fde4e6d49c3..314b98e41b74149b2fcd7c765f6c4b87114dd86c 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -463,11 +463,11 @@ void HLSWriter::codePPS( const PPS* pcPPS ) } #endif #if JVET_X0071_CHROMA_BILATERAL_FILTER - WRITE_FLAG(pcPPS->getUseCBIF() ? 1 : 0, "chroma bilateral_filter_flag" ); - if(pcPPS->getUseCBIF()) + WRITE_FLAG(pcPPS->getUseChromaBIF() ? 1 : 0, "chroma bilateral_filter_flag" ); + if(pcPPS->getUseChromaBIF()) { - WRITE_CODE( pcPPS->getCBIFStrength(), 2, "chroma bilateral_filter_strength"); - WRITE_SVLC( pcPPS->getCBIFQPOffset(), "chroma bilateral_filter_qp_offset"); + WRITE_CODE( pcPPS->getChromaBIFStrength(), 2, "chroma bilateral_filter_strength"); + WRITE_SVLC( pcPPS->getChromaBIFQPOffset(), "chroma bilateral_filter_qp_offset"); } #endif #if !JVET_S0132_HLS_REORDER