diff --git a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp index d72a40f53d81d06aff045659c36f7f362af08e8b..4d862ff95008c1b7543b0f1d53f480f329e066ea 100644 --- a/source/Lib/CommonLib/AdaptiveLoopFilter.cpp +++ b/source/Lib/CommonLib/AdaptiveLoopFilter.cpp @@ -294,20 +294,16 @@ void AdaptiveLoopFilter::applyCcAlfFilter(CodingStructure &cs, ComponentID compI const short filterSet[MAX_NUM_CC_ALF_FILTERS][MAX_NUM_CC_ALF_CHROMA_COEFF], const int selectedFilterIdx) { + bool clipTop = false, clipBottom = false, clipLeft = false, clipRight = false; + int numHorVirBndry = 0, numVerVirBndry = 0; + int horVirBndryPos[] = { 0, 0, 0 }; + int verVirBndryPos[] = { 0, 0, 0 }; + int ctuIdx = 0; for( int yPos = 0; yPos < m_picHeight; yPos += m_maxCUHeight ) { for( int xPos = 0; xPos < m_picWidth; xPos += m_maxCUWidth ) { - const int width = ( xPos + m_maxCUWidth > m_picWidth ) ? ( m_picWidth - xPos ) : m_maxCUWidth; - const int height = ( yPos + m_maxCUHeight > m_picHeight ) ? ( m_picHeight - yPos ) : m_maxCUHeight; - const UnitArea area( m_chromaFormat, Area( xPos, yPos, width, height ) ); - const int chromaScaleX = getComponentScaleX( compID, m_chromaFormat ); - const int chromaScaleY = getComponentScaleY( compID, m_chromaFormat ); - - Area blkDst(xPos >> chromaScaleX, yPos >> chromaScaleY, width >> chromaScaleX, height >> chromaScaleY); - Area blkSrc(xPos, yPos, width, height); - int filterIdx = (filterControl == nullptr) ? selectedFilterIdx @@ -320,8 +316,73 @@ void AdaptiveLoopFilter::applyCcAlfFilter(CodingStructure &cs, ComponentID compI const int16_t *filterCoeff = filterSet[filterIdx]; - m_filterCcAlf(dstBuf, recYuvExt, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, m_alfVBLumaCTUHeight, - m_alfVBLumaPos); + const int width = (xPos + m_maxCUWidth > m_picWidth) ? (m_picWidth - xPos) : m_maxCUWidth; + const int height = (yPos + m_maxCUHeight > m_picHeight) ? (m_picHeight - yPos) : m_maxCUHeight; + const int chromaScaleX = getComponentScaleX(compID, m_chromaFormat); + const int chromaScaleY = getComponentScaleY(compID, m_chromaFormat); + + int rasterSliceAlfPad = 0; + if (isCrossedByVirtualBoundaries(cs, xPos, yPos, width, height, clipTop, clipBottom, clipLeft, clipRight, + numHorVirBndry, numVerVirBndry, horVirBndryPos, verVirBndryPos, + rasterSliceAlfPad)) + { + int yStart = yPos; + for (int i = 0; i <= numHorVirBndry; i++) + { + const int yEnd = i == numHorVirBndry ? yPos + height : horVirBndryPos[i]; + const int h = yEnd - yStart; + const bool clipT = (i == 0 && clipTop) || (i > 0) || (yStart == 0); + const bool clipB = (i == numHorVirBndry && clipBottom) || (i < numHorVirBndry) || (yEnd == m_picHeight); + int xStart = xPos; + for (int j = 0; j <= numVerVirBndry; j++) + { + const int xEnd = j == numVerVirBndry ? xPos + width : verVirBndryPos[j]; + const int w = xEnd - xStart; + const bool clipL = (j == 0 && clipLeft) || (j > 0) || (xStart == 0); + const bool clipR = (j == numVerVirBndry && clipRight) || (j < numVerVirBndry) || (xEnd == m_picWidth); + const int wBuf = w + (clipL ? 0 : MAX_ALF_PADDING_SIZE) + (clipR ? 0 : MAX_ALF_PADDING_SIZE); + const int hBuf = h + (clipT ? 0 : MAX_ALF_PADDING_SIZE) + (clipB ? 0 : MAX_ALF_PADDING_SIZE); + PelUnitBuf buf = m_tempBuf2.subBuf(UnitArea(cs.area.chromaFormat, Area(0, 0, wBuf, hBuf))); + buf.copyFrom(recYuvExt.subBuf( + UnitArea(cs.area.chromaFormat, Area(xStart - (clipL ? 0 : MAX_ALF_PADDING_SIZE), + yStart - (clipT ? 0 : MAX_ALF_PADDING_SIZE), wBuf, hBuf)))); + // pad top-left unavailable samples for raster slice + if (xStart == xPos && yStart == yPos && (rasterSliceAlfPad & 1)) + { + buf.padBorderPel(MAX_ALF_PADDING_SIZE, 1); + } + + // pad bottom-right unavailable samples for raster slice + if (xEnd == xPos + width && yEnd == yPos + height && (rasterSliceAlfPad & 2)) + { + buf.padBorderPel(MAX_ALF_PADDING_SIZE, 2); + } + buf.extendBorderPel(MAX_ALF_PADDING_SIZE); + buf = buf.subBuf(UnitArea( + cs.area.chromaFormat, Area(clipL ? 0 : MAX_ALF_PADDING_SIZE, clipT ? 0 : MAX_ALF_PADDING_SIZE, w, h))); + + const Area blkSrc(0, 0, w, h); + + const Area blkDst(xStart >> chromaScaleX, yStart >> chromaScaleY, w >> chromaScaleX, h >> chromaScaleY); + m_filterCcAlf(dstBuf, buf, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, m_alfVBLumaCTUHeight, + m_alfVBLumaPos); + + xStart = xEnd; + } + + yStart = yEnd; + } + } + else + { + const UnitArea area(m_chromaFormat, Area(xPos, yPos, width, height)); + + Area blkDst(xPos >> chromaScaleX, yPos >> chromaScaleY, width >> chromaScaleX, height >> chromaScaleY); + Area blkSrc(xPos, yPos, width, height); + + m_filterCcAlf(dstBuf, recYuvExt, blkDst, blkSrc, compID, filterCoeff, m_clpRngs, cs, m_alfVBLumaCTUHeight, + m_alfVBLumaPos); + } } ctuIdx++; }