/* The copyright in this software is being made available under the BSD * License, included below. This software may be subject to other third party * and contributor rights, including patent rights, and no such rights are * granted under this license. * * Copyright (c) 2010-2011, ISO/IEC * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the ISO/IEC nor the names of its contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ /** \file TComPattern.cpp \brief neighbouring pixel access classes */ #include "TComPic.h" #include "TComPattern.h" #include "TComDataCU.h" // ==================================================================================================================== // Tables // ==================================================================================================================== const UChar g_aaucAvailableBlkMask[16][8] = { // 4x4 block neighbor availability // MB neighbor availability {0x0,0x0,0x0,0x0, 0x0,0x8,0x0,0x08 }, // L, A, AL, AR <== WTF (blkIdx < 8) {0x1,0x0,0x0,0x0, 0x1,0x8,0x0,0x08 }, // A, AL, AR {0xA,0xE,0xE,0x6, 0x0,0x8,0x0,0x08 }, // L, AL, AR {0xB,0xE,0xE,0x6, 0x1,0x8,0x0,0x08 }, // AL, AR {0x4,0x0,0x0,0x0, 0x0,0x8,0x0,0x08 }, // L, A, AR {0x5,0x0,0x0,0x0, 0x1,0x8,0x0,0x08 }, // A, AR {0xE,0xE,0xE,0x6, 0x0,0x8,0x0,0x08 }, // L, AR {0xF,0xE,0xE,0x6, 0x1,0x8,0x0,0x08 }, // AR {0x0,0x0,0x0,0x8, 0x0,0x8,0x0,0x08 }, // L, A, AL <== WTF (blkIdx < 8 || blkIdx >= 8) {0x1,0x0,0x0,0x8, 0x1,0x8,0x0,0x08 }, // A, AL {0xA,0xE,0xE,0xE, 0x0,0x8,0x0,0x08 }, // L, AL {0xB,0xE,0xE,0xE, 0x1,0x8,0x0,0x08 }, // AL {0x4,0x0,0x0,0x8, 0x0,0x8,0x0,0x08 }, // L, A, {0x5,0x0,0x0,0x8, 0x1,0x8,0x0,0x08 }, // A, {0xE,0xE,0xE,0xE, 0x0,0x8,0x0,0x08 }, // L, {0xF,0xE,0xE,0xE, 0x1,0x8,0x0,0x08 } // }; // ==================================================================================================================== // Public member functions (TComPatternParam) // ==================================================================================================================== /** \param piTexture pixel data \param iRoiWidth pattern width \param iRoiHeight pattern height \param iStride buffer stride \param iOffsetLeft neighbour offset (left) \param iOffsetRight neighbour offset (right) \param iOffsetAbove neighbour offset (above) \param iOffsetBottom neighbour offset (bottom) */ Void TComPatternParam::setPatternParamPel ( Pel* piTexture, Int iRoiWidth, Int iRoiHeight, Int iStride, Int iOffsetLeft, Int iOffsetRight, Int iOffsetAbove, Int iOffsetBottom ) { m_piPatternOrigin = piTexture; m_iROIWidth = iRoiWidth; m_iROIHeight = iRoiHeight; m_iPatternStride = iStride; m_iOffsetLeft = iOffsetLeft; m_iOffsetAbove = iOffsetAbove; m_iOffsetRight = iOffsetRight; m_iOffsetBottom = iOffsetBottom; } /** \param pcCU CU data structure \param iComp component index (0=Y, 1=Cb, 2=Cr) \param iRoiWidth pattern width \param iRoiHeight pattern height \param iStride buffer stride \param iOffsetLeft neighbour offset (left) \param iOffsetRight neighbour offset (right) \param iOffsetAbove neighbour offset (above) \param iOffsetBottom neighbour offset (bottom) \param uiPartDepth CU depth \param uiAbsPartIdx part index */ Void TComPatternParam::setPatternParamCU( TComDataCU* pcCU, UChar iComp, UChar iRoiWidth, UChar iRoiHeight, Int iOffsetLeft, Int iOffsetRight, Int iOffsetAbove, Int iOffsetBottom, UInt uiPartDepth, UInt uiAbsPartIdx #if DEPTH_MAP_GENERATION ,Bool bPrdDepthMap #endif ) { m_iOffsetLeft = iOffsetLeft; m_iOffsetRight = iOffsetRight; m_iOffsetAbove = iOffsetAbove; m_iOffsetBottom = iOffsetBottom; m_iROIWidth = iRoiWidth; m_iROIHeight = iRoiHeight; UInt uiAbsZorderIdx = pcCU->getZorderIdxInCU() + uiAbsPartIdx; #if DEPTH_MAP_GENERATION TComPicYuv* pcPic = ( bPrdDepthMap ? pcCU->getPic()->getPredDepthMap() : pcCU->getPic()->getPicYuvRec() ); #else TComPicYuv* pcPic = pcCU->getPic()->getPicYuvRec(); #endif if ( iComp == 0 ) { #if DEPTH_MAP_GENERATION m_iPatternStride = ( bPrdDepthMap ? pcCU->getPic()->getPredDepthMap()->getStride() : pcCU->getPic()->getStride() ); #else m_iPatternStride = pcCU->getPic()->getStride(); #endif m_piPatternOrigin = pcPic->getLumaAddr(pcCU->getAddr(), uiAbsZorderIdx) - m_iOffsetAbove * m_iPatternStride - m_iOffsetLeft; } else { #if DEPTH_MAP_GENERATION m_iPatternStride = ( bPrdDepthMap ? pcCU->getPic()->getPredDepthMap()->getCStride() : pcCU->getPic()->getCStride() ); #else m_iPatternStride = pcCU->getPic()->getCStride(); #endif if ( iComp == 1 ) m_piPatternOrigin = pcPic->getCbAddr(pcCU->getAddr(), uiAbsZorderIdx) - m_iOffsetAbove * m_iPatternStride - m_iOffsetLeft; else m_piPatternOrigin = pcPic->getCrAddr(pcCU->getAddr(), uiAbsZorderIdx) - m_iOffsetAbove * m_iPatternStride - m_iOffsetLeft; } } // ==================================================================================================================== // Public member functions (TComPattern) // ==================================================================================================================== Void TComPattern::initPattern ( Pel* piY, Pel* piCb, Pel* piCr, Int iRoiWidth, Int iRoiHeight, Int iStride, Int iOffsetLeft, Int iOffsetRight, Int iOffsetAbove, Int iOffsetBottom ) { m_cPatternY. setPatternParamPel( piY, iRoiWidth, iRoiHeight, iStride, iOffsetLeft, iOffsetRight, iOffsetAbove, iOffsetBottom ); m_cPatternCb.setPatternParamPel( piCb, iRoiWidth >> 1, iRoiHeight >> 1, iStride >> 1, iOffsetLeft >> 1, iOffsetRight >> 1, iOffsetAbove >> 1, iOffsetBottom >> 1 ); m_cPatternCr.setPatternParamPel( piCr, iRoiWidth >> 1, iRoiHeight >> 1, iStride >> 1, iOffsetLeft >> 1, iOffsetRight >> 1, iOffsetAbove >> 1, iOffsetBottom >> 1 ); return; } Void TComPattern::initPattern( TComDataCU* pcCU, UInt uiPartDepth, UInt uiAbsPartIdx #if DEPTH_MAP_GENERATION , Bool bPrdDepthMap #endif ) { Int uiOffsetLeft = 0; Int uiOffsetRight = 0; Int uiOffsetAbove = 0; TComPic* pcPic = pcCU->getPic(); UChar uiWidth = pcCU->getWidth (0)>>uiPartDepth; UChar uiHeight = pcCU->getHeight(0)>>uiPartDepth; UInt uiAbsZorderIdx = pcCU->getZorderIdxInCU() + uiAbsPartIdx; UInt uiCurrPicPelX = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ]; UInt uiCurrPicPelY = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ]; if( uiCurrPicPelX != 0 ) uiOffsetLeft = 1; if( uiCurrPicPelY != 0 ) { UInt uiNumPartInWidth = ( uiWidth/pcPic->getMinCUWidth() ); uiOffsetAbove = 1; if( uiCurrPicPelX + uiWidth < pcCU->getSlice()->getSPS()->getWidth() ) { if( ( g_auiZscanToRaster[uiAbsZorderIdx] + uiNumPartInWidth ) % pcPic->getNumPartInWidth() ) // Not CU boundary { if( g_auiRasterToZscan[ (Int)g_auiZscanToRaster[uiAbsZorderIdx] - (Int)pcPic->getNumPartInWidth() + (Int)uiNumPartInWidth ] < uiAbsZorderIdx ) uiOffsetRight = 1; } else // if it is CU boundary { if( g_auiZscanToRaster[uiAbsZorderIdx] < pcPic->getNumPartInWidth() && (uiCurrPicPelX+uiWidth) < pcPic->getPicYuvRec()->getWidth() ) // first line { uiOffsetRight = 1; } } } } #if LM_CHROMA m_bLeftAvailable = uiCurrPicPelX > 0 ? true : false; m_bAboveAvailable = uiCurrPicPelY > 0 ? true : false; #endif #if DEPTH_MAP_GENERATION m_cPatternY .setPatternParamCU( pcCU, 0, uiWidth, uiHeight, uiOffsetLeft, uiOffsetRight, uiOffsetAbove, 0, uiPartDepth, uiAbsPartIdx, bPrdDepthMap ); m_cPatternCb.setPatternParamCU( pcCU, 1, uiWidth >> 1, uiHeight >> 1, uiOffsetLeft, uiOffsetRight, uiOffsetAbove, 0, uiPartDepth, uiAbsPartIdx, bPrdDepthMap ); m_cPatternCr.setPatternParamCU( pcCU, 2, uiWidth >> 1, uiHeight >> 1, uiOffsetLeft, uiOffsetRight, uiOffsetAbove, 0, uiPartDepth, uiAbsPartIdx, bPrdDepthMap ); #else m_cPatternY .setPatternParamCU( pcCU, 0, uiWidth, uiHeight, uiOffsetLeft, uiOffsetRight, uiOffsetAbove, 0, uiPartDepth, uiAbsPartIdx ); m_cPatternCb.setPatternParamCU( pcCU, 1, uiWidth >> 1, uiHeight >> 1, uiOffsetLeft, uiOffsetRight, uiOffsetAbove, 0, uiPartDepth, uiAbsPartIdx ); m_cPatternCr.setPatternParamCU( pcCU, 2, uiWidth >> 1, uiHeight >> 1, uiOffsetLeft, uiOffsetRight, uiOffsetAbove, 0, uiPartDepth, uiAbsPartIdx ); #endif } Void TComPattern::initAdiPattern( TComDataCU* pcCU, UInt uiZorderIdxInPart, UInt uiPartDepth, Int* piAdiBuf, Int iOrgBufStride, Int iOrgBufHeight, Bool& bAbove, Bool& bLeft #if DEPTH_MAP_GENERATION , Bool bPrdDepthMap, UInt uiSubSampExpX, UInt uiSubSampExpY #endif ) { Pel* piRoiOrigin; Int* piAdiTemp; UInt uiCuWidth = pcCU->getWidth(0) >> uiPartDepth; UInt uiCuHeight = pcCU->getHeight(0)>> uiPartDepth; UInt uiCuWidth2 = uiCuWidth<<1; UInt uiCuHeight2 = uiCuHeight<<1; UInt uiWidth; UInt uiHeight; #if DEPTH_MAP_GENERATION Int iPicStride = ( bPrdDepthMap ? pcCU->getPic()->getPredDepthMap()->getStride() : pcCU->getPic()->getStride() ); #else Int iPicStride = pcCU->getPic()->getStride(); #endif Int iCuAddr; #if REFERENCE_SAMPLE_PADDING Int iUnitSize = 0; Int iNumUnitsInCu = 0; Int iTotalUnits = 0; Bool* bNeighborFlags; Int iNumIntraNeighbor = 0; #else // REFERENCE_SAMPLE_PADDING Pel* piRoiTemp; Bool bAboveFlag = false; Bool bAboveRightFlag = false; Bool bLeftFlag = false; Bool bBelowLeftFlag = false; Bool bAboveLeftFlag = false; #endif // REFERENCE_SAMPLE_PADDING iCuAddr = pcCU->getAddr(); UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB, uiPartDum; pcCU->deriveLeftRightTopIdxAdi( uiPartIdxLT, uiPartIdxRT, uiZorderIdxInPart, uiPartDepth ); pcCU->deriveLeftBottomIdxAdi ( uiPartIdxLB, uiZorderIdxInPart, uiPartDepth ); #if CONSTRAINED_INTRA_PRED if ( pcCU->getSlice()->getPPS()->getConstrainedIntraPred() ) { #if REFERENCE_SAMPLE_PADDING iUnitSize = g_uiMaxCUWidth >> g_uiMaxCUDepth; iNumUnitsInCu = uiCuWidth / iUnitSize; iTotalUnits = (iNumUnitsInCu << 2) + 1; bNeighborFlags = new Bool[iTotalUnits]; bNeighborFlags[iNumUnitsInCu*2] = isAboveLeftAvailableForCIP( pcCU, uiPartIdxLT ); iNumIntraNeighbor += (Int)(bNeighborFlags[iNumUnitsInCu*2]); iNumIntraNeighbor += isAboveAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*2)+1 ); iNumIntraNeighbor += isAboveRightAvailableForCIP( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*3)+1 ); iNumIntraNeighbor += isLeftAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+(iNumUnitsInCu*2)-1 ); iNumIntraNeighbor += isBelowLeftAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+ iNumUnitsInCu -1 ); #else // REFERENCE_SAMPLE_PADDING bAboveFlag = isAboveAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxRT ); bAboveRightFlag = isAboveRightAvailableForCIP( pcCU, uiPartIdxLT, uiPartIdxRT ); bLeftFlag = isLeftAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxLB ); bBelowLeftFlag = isBelowLeftAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxLB ); bAboveLeftFlag = isAboveLeftAvailableForCIP ( pcCU, uiPartIdxLT ); #endif // REFERENCE_SAMPLE_PADDING } else { #if REFERENCE_SAMPLE_PADDING iUnitSize = uiCuWidth; iNumUnitsInCu = 1; iTotalUnits = 5; bNeighborFlags = new Bool[iTotalUnits]; ::memset(bNeighborFlags, false, sizeof(Bool)*iTotalUnits); if( pcCU->getPUAbove ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[3] = true; iNumIntraNeighbor++; } if( pcCU->getPUAboveRightAdi( uiPartDum, uiCuWidth, uiPartIdxRT, 1, true, false ) ) { bNeighborFlags[4] = true; iNumIntraNeighbor++; } if( pcCU->getPULeft ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[1] = true; iNumIntraNeighbor++; } if( pcCU->getPUBelowLeftAdi ( uiPartDum, uiCuHeight, uiPartIdxLB, 1, true, false ) ) { bNeighborFlags[0] = true; iNumIntraNeighbor++; } if( pcCU->getPUAboveLeft ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[2] = true; iNumIntraNeighbor++; } #if MN_DC_PRED_FILTER m_bAboveFlagForDCFilt = bNeighborFlags[3]; m_bLeftFlagForDCFilt = bNeighborFlags[1]; #endif #else // REFERENCE_SAMPLE_PADDING if( pcCU->getPUAbove ( uiPartDum, uiPartIdxLT, true, false ) ) bAboveFlag = true; if( pcCU->getPUAboveRightAdi( uiPartDum, uiCuWidth, uiPartIdxRT, 1, true, false ) ) bAboveRightFlag = true; if( pcCU->getPULeft ( uiPartDum, uiPartIdxLT, true, false ) ) bLeftFlag = true; if( pcCU->getPUBelowLeftAdi ( uiPartDum, uiCuHeight, uiPartIdxLB, 1, true, false ) ) bBelowLeftFlag = true; if( pcCU->getPUAboveLeft ( uiPartDum, uiPartIdxLT, true, false ) ) bAboveLeftFlag = true; #if MN_DC_PRED_FILTER m_bAboveFlagForDCFilt = bAboveFlag; m_bLeftFlagForDCFilt = bLeftFlag; #endif #endif // REFERENCE_SAMPLE_PADDING } #else //CONSTRAINED_INTRA_PRED #if REFERENCE_SAMPLE_PADDING iUnitSize = uiCuWidth; iNumUnitsInCu = 1; iTotalUnits = 5; bNeighborFlags = new Bool[iTotalUnits]; ::memset(bNeighborFlags, false, sizeof(Bool)*iTotalUnits); if( pcCU->getPUAbove ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[3] = true; iNumIntraNeighbor++; } if( pcCU->getPUAboveRightAdi( uiPartDum, uiCuWidth, uiPartIdxRT, true, false ) ) { bNeighborFlags[4] = true; iNumIntraNeighbor++; } if( pcCU->getPULeft ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[1] = true; iNumIntraNeighbor++; } if( pcCU->getPUBelowLeftAdi ( uiPartDum, uiCuHeight, uiPartIdxLB, true, false ) ) { bNeighborFlags[0] = true; iNumIntraNeighbor++; } if( pcCU->getPUAboveLeft ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[2] = true; iNumIntraNeighbor++; } #if MN_DC_PRED_FILTER m_bAboveFlagForDCFilt = bNeighborFlags[3]; m_bLeftFlagForDCFilt = bNeighborFlags[1]; #endif #else // REFERENCE_SAMPLE_PADDING if( pcCU->getPUAbove ( uiPartDum, uiPartIdxLT, true, false ) ) bAboveFlag = true; if( pcCU->getPUAboveRightAdi( uiPartDum, uiCuWidth, uiPartIdxRT, true, false ) ) bAboveRightFlag = true; if( pcCU->getPULeft ( uiPartDum, uiPartIdxLT, true, false ) ) bLeftFlag = true; if( pcCU->getPUBelowLeftAdi ( uiPartDum, uiCuHeight, uiPartIdxLB, true, false ) ) bBelowLeftFlag = true; if( pcCU->getPUAboveLeft ( uiPartDum, uiPartIdxLT, true, false ) ) bAboveLeftFlag = true; #if MN_DC_PRED_FILTER m_bAboveFlagForDCFilt = bAboveFlag; m_bLeftFlagForDCFilt = bLeftFlag; #endif #endif // REFERENCE_SAMPLE_PADDING #endif //CONSTRAINED_INTRA_PRED #if MN_DC_PRED_FILTER m_bDCPredFilterFlag = (m_bAboveFlagForDCFilt && m_bLeftFlagForDCFilt) ? true : false; #endif #if REFERENCE_SAMPLE_PADDING bAbove = true; bLeft = true; #else // REFERENCE_SAMPLE_PADDING bAbove = bAboveFlag; bLeft = bLeftFlag; Int iDCValue = ( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) ); #endif // REFERENCE_SAMPLE_PADDING #if DEPTH_MAP_GENERATION if ( bPrdDepthMap ) { uiWidth = ( uiCuWidth2 >> uiSubSampExpX ) + 1; uiHeight = ( uiCuHeight2 >> uiSubSampExpY ) + 1; } else { uiWidth=uiCuWidth2+1; uiHeight=uiCuHeight2+1; } #else uiWidth=uiCuWidth2+1; uiHeight=uiCuHeight2+1; #endif if (((uiWidth<<2)>iOrgBufStride)||((uiHeight<<2)>iOrgBufHeight)) return; piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getLumaAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiZorderIdxInPart); piAdiTemp = piAdiBuf; #if DEPTH_MAP_GENERATION if( bPrdDepthMap ) { piRoiOrigin = pcCU->getPic()->getPredDepthMap()->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiZorderIdxInPart ); #if REFERENCE_SAMPLE_PADDING #else iDCValue = PDM_UNDEFINED_DEPTH; #endif } #endif #if REFERENCE_SAMPLE_PADDING #if DEPTH_MAP_GENERATION if ( bPrdDepthMap ) fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize >> uiSubSampExpX, iNumUnitsInCu, iTotalUnits, uiCuWidth >> uiSubSampExpX, uiCuHeight >> uiSubSampExpY, uiWidth, uiHeight, iPicStride, bPrdDepthMap ); else fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride, bPrdDepthMap ); #else fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride ); #endif delete [] bNeighborFlags; bNeighborFlags = NULL; #else // REFERENCE_SAMPLE_PADDING //BB: fill border with DC value - needed if( bAboveFlag=false || bLeftFlag=false ) for (i=0;i> 2; // fill 1. filter buffer with filtered values l=0; for (i = 0; i < uiCuHeight2; i++) piFilteredBuf1[uiWidth * (uiCuHeight2 - i)] = piFilterBufN[l++]; piFilteredBuf1[0] = piFilterBufN[l++]; for (i = 0; i < uiCuWidth2; i++) piFilteredBuf1[1 + i] = piFilterBufN[l++]; #if !MN_MDIS_SIMPLIFICATION // 2. filtering with [1 2 1] piFilterBuf[0] = piFilterBufN[0]; piFilterBuf[iBufSize - 1] = piFilterBufN[iBufSize - 1]; for (i = 1; i < iBufSize - 1; i++) piFilterBuf[i] = (piFilterBufN[i - 1] + 2 * piFilterBufN[i] + piFilterBufN[i + 1] + 2) >> 2; // fill 2. filter buffer with filtered values l=0; for (i = 0; i < uiCuHeight2; i++) piFilteredBuf2[uiWidth * (uiCuHeight2 - i)] = piFilterBuf[l++]; piFilteredBuf2[0] = piFilterBuf[l++]; for (i = 0; i < uiCuWidth2; i++) piFilteredBuf2[1 + i] = piFilterBuf[l++]; #endif #endif //QC_MDIS } Void TComPattern::initAdiPatternChroma( TComDataCU* pcCU, UInt uiZorderIdxInPart, UInt uiPartDepth, Int* piAdiBuf, Int iOrgBufStride, Int iOrgBufHeight, Bool& bAbove, Bool& bLeft ) { Pel* piRoiOrigin; Int* piAdiTemp; UInt uiCuWidth = pcCU->getWidth (0) >> uiPartDepth; UInt uiCuHeight = pcCU->getHeight(0) >> uiPartDepth; UInt uiWidth; UInt uiHeight; Int iPicStride = pcCU->getPic()->getCStride(); Int iCuAddr; #if REFERENCE_SAMPLE_PADDING Int iUnitSize = 0; Int iNumUnitsInCu = 0; Int iTotalUnits = 0; Bool* bNeighborFlags; Int iNumIntraNeighbor = 0; #else // REFERENCE_SAMPLE_PADDING Pel* piRoiTemp; Int i; Bool bAboveFlag=false; Bool bAboveRightFlag=false; Bool bLeftFlag=false; Bool bBelowLeftFlag=false; Bool bAboveLeftFlag = false; #endif // REFERENCE_SAMPLE_PADDING iCuAddr = pcCU->getAddr(); UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB,uiPartDum; pcCU->deriveLeftRightTopIdxAdi( uiPartIdxLT, uiPartIdxRT, uiZorderIdxInPart, uiPartDepth ); pcCU->deriveLeftBottomIdxAdi ( uiPartIdxLB, uiZorderIdxInPart, uiPartDepth ); #if CONSTRAINED_INTRA_PRED if ( pcCU->getSlice()->getPPS()->getConstrainedIntraPred() ) { #if REFERENCE_SAMPLE_PADDING iUnitSize = (g_uiMaxCUWidth >> g_uiMaxCUDepth) >> 1; // for chroma iNumUnitsInCu = (uiCuWidth / iUnitSize) >> 1; // for chroma iTotalUnits = (iNumUnitsInCu << 2) + 1; bNeighborFlags = new Bool[iTotalUnits]; bNeighborFlags[iNumUnitsInCu*2] = isAboveLeftAvailableForCIP( pcCU, uiPartIdxLT ); iNumIntraNeighbor += (Int)(bNeighborFlags[iNumUnitsInCu*2]); iNumIntraNeighbor += isAboveAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*2)+1 ); iNumIntraNeighbor += isAboveRightAvailableForCIP( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*3)+1 ); iNumIntraNeighbor += isLeftAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+(iNumUnitsInCu*2)-1 ); iNumIntraNeighbor += isBelowLeftAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+ iNumUnitsInCu -1 ); #else // REFERENCE_SAMPLE_PADDING bAboveFlag = isAboveAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxRT ); bAboveRightFlag = isAboveRightAvailableForCIP( pcCU, uiPartIdxLT, uiPartIdxRT ); bLeftFlag = isLeftAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxLB ); bBelowLeftFlag = isBelowLeftAvailableForCIP ( pcCU, uiPartIdxLT, uiPartIdxLB ); bAboveLeftFlag = isAboveLeftAvailableForCIP ( pcCU, uiPartIdxLT ); #endif // REFERENCE_SAMPLE_PADDING } else { #if REFERENCE_SAMPLE_PADDING iUnitSize = uiCuWidth >> 1; iNumUnitsInCu = 1; iTotalUnits = 5; bNeighborFlags = new Bool[iTotalUnits]; ::memset(bNeighborFlags, false, sizeof(Bool)*iTotalUnits); if( pcCU->getPUAbove ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[3] = true; iNumIntraNeighbor++; } if( pcCU->getPUAboveRightAdi( uiPartDum, uiCuWidth, uiPartIdxRT, 1, true, false ) ) { bNeighborFlags[4] = true; iNumIntraNeighbor++; } if( pcCU->getPULeft ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[1] = true; iNumIntraNeighbor++; } if( pcCU->getPUBelowLeftAdi ( uiPartDum, uiCuHeight, uiPartIdxLB, 1, true, false ) ) { bNeighborFlags[0] = true; iNumIntraNeighbor++; } if( pcCU->getPUAboveLeft ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[2] = true; iNumIntraNeighbor++; } #else // REFERENCE_SAMPLE_PADDING if( pcCU->getPUAbove ( uiPartDum, uiPartIdxLT, true, false ) ) bAboveFlag = true; if( pcCU->getPUAboveRightAdi( uiPartDum, uiCuWidth, uiPartIdxRT, 1, true, false ) ) bAboveRightFlag = true; if( pcCU->getPULeft ( uiPartDum, uiPartIdxLT, true, false ) ) bLeftFlag = true; if( pcCU->getPUBelowLeftAdi ( uiPartDum, uiCuHeight, uiPartIdxLB, 1, true, false ) ) bBelowLeftFlag = true; if( pcCU->getPUAboveLeft ( uiPartDum, uiPartIdxLT, true, false ) ) bAboveLeftFlag = true; #endif // REFERENCE_SAMPLE_PADDING } #else //CONSTRAINED_INTRA_PRED #if REFERENCE_SAMPLE_PADDING iUnitSize = uiCuWidth >> 1; iNumUnitsInCu = 1; iTotalUnits = 5; bNeighborFlags = new Bool[iTotalUnits]; ::memset(bNeighborFlags, false, sizeof(Bool)*iTotalUnits); if( pcCU->getPUAbove ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[3] = true; iNumIntraNeighbor++; } if( pcCU->getPUAboveRightAdi( uiPartDum, uiCuWidth, uiPartIdxRT, true, false ) ) { bNeighborFlags[4] = true; iNumIntraNeighbor++; } if( pcCU->getPULeft ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[1] = true; iNumIntraNeighbor++; } if( pcCU->getPUBelowLeftAdi ( uiPartDum, uiCuHeight, uiPartIdxLB, true, false ) ) { bNeighborFlags[0] = true; iNumIntraNeighbor++; } if( pcCU->getPUAboveLeft ( uiPartDum, uiPartIdxLT, true, false ) ) { bNeighborFlags[2] = true; iNumIntraNeighbor++; } #else // REFERENCE_SAMPLE_PADDING if( pcCU->getPUAbove ( uiPartDum, uiPartIdxLT, true, false ) ) bAboveFlag = true; if( pcCU->getPUAboveRightAdi( uiPartDum, uiCuWidth, uiPartIdxRT, true, false ) ) bAboveRightFlag = true; if( pcCU->getPULeft ( uiPartDum, uiPartIdxLT, true, false ) ) bLeftFlag = true; if( pcCU->getPUBelowLeftAdi ( uiPartDum, uiCuHeight, uiPartIdxLB, true, false ) ) bBelowLeftFlag = true; if( pcCU->getPUAboveLeft ( uiPartDum, uiPartIdxLT, true, false ) ) bAboveLeftFlag = true; #endif // REFERENCE_SAMPLE_PADDING #endif //CONSTRAINED_INTRA_PRED #if REFERENCE_SAMPLE_PADDING bAbove = true; bLeft = true; #else // REFERENCE_SAMPLE_PADDING bAbove = bAboveFlag; bLeft = bLeftFlag; Int iDCValue = ( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) ); #endif // REFERENCE_SAMPLE_PADDING uiCuWidth=uiCuWidth>>1; // for chroma uiCuHeight=uiCuHeight>>1; // for chroma uiWidth=uiCuWidth*2+1; uiHeight=uiCuHeight*2+1; if ((4*uiWidth>iOrgBufStride)||(4*uiHeight>iOrgBufHeight)) return; // get Cb pattern piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getCbAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiZorderIdxInPart); piAdiTemp = piAdiBuf; #if REFERENCE_SAMPLE_PADDING #if DEPTH_MAP_GENERATION fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride, false ); #else fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride ); #endif #else // REFERENCE_SAMPLE_PADDING for (i=0;igetPic()->getPicYuvRec()->getCrAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiZorderIdxInPart); piAdiTemp = piAdiBuf+uiWidth*uiHeight; #if REFERENCE_SAMPLE_PADDING #if DEPTH_MAP_GENERATION fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride, false ); #else fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride ); #endif delete [] bNeighborFlags; bNeighborFlags = NULL; #else // REFERENCE_SAMPLE_PADDING for (i=0;i= 0 && iNext < iTotalUnits) piRef = (piAdiLine[iCurr*iUnitSize-1] + piAdiLine[iNext*iUnitSize] + 1) >> 1; else if (iPrev >= 0) piRef = piAdiLine[iCurr*iUnitSize-1]; else if (iNext < iTotalUnits) piRef = piAdiLine[iNext*iUnitSize]; else printf("\nERROR! No valid samples to interpolate.\n"); // Pad unavailable samples with new value while (iCurr < iNext) { for (i=0; igetPUAboveLeft( uiPartAboveLeft, uiPartIdxLT, true, false ); bAboveLeftFlag = ( pcCUAboveLeft && pcCUAboveLeft->getPredictionMode( uiPartAboveLeft ) == MODE_INTRA ); return bAboveLeftFlag; } #if REFERENCE_SAMPLE_PADDING Int TComPattern::isAboveAvailableForCIP( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags ) #else Bool TComPattern::isAboveAvailableForCIP( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT ) #endif { const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT]; const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxRT]+1; const UInt uiIdxStep = 1; #if REFERENCE_SAMPLE_PADDING Bool *pbValidFlags = bValidFlags; Int iNumIntra = 0; #else Bool bAboveFlag = true; #endif #if MN_DC_PRED_FILTER m_bAboveFlagForDCFilt = true; #endif for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep ) { UInt uiPartAbove; TComDataCU* pcCUAbove = pcCU->getPUAbove( uiPartAbove, g_auiRasterToZscan[uiRasterPart], true, false ); #if REFERENCE_SAMPLE_PADDING if ( pcCUAbove && pcCUAbove->getPredictionMode( uiPartAbove ) == MODE_INTRA ) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; #if MN_DC_PRED_FILTER m_bAboveFlagForDCFilt = false; #endif } pbValidFlags++; #else if ( !pcCUAbove || pcCUAbove->getPredictionMode( uiPartAbove ) != MODE_INTRA ) { bAboveFlag = false; #if MN_DC_PRED_FILTER m_bAboveFlagForDCFilt = false; #endif break; } #endif } #if REFERENCE_SAMPLE_PADDING return iNumIntra; #else return bAboveFlag; #endif } #if REFERENCE_SAMPLE_PADDING Int TComPattern::isLeftAvailableForCIP( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags ) #else Bool TComPattern::isLeftAvailableForCIP( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB ) #endif { const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT]; const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxLB]+1; const UInt uiIdxStep = pcCU->getPic()->getNumPartInWidth(); #if REFERENCE_SAMPLE_PADDING Bool *pbValidFlags = bValidFlags; Int iNumIntra = 0; #else Bool bLeftFlag = true; #endif #if MN_DC_PRED_FILTER m_bLeftFlagForDCFilt = true; #endif for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep ) { UInt uiPartLeft; TComDataCU* pcCULeft = pcCU->getPULeft( uiPartLeft, g_auiRasterToZscan[uiRasterPart], true, false ); #if REFERENCE_SAMPLE_PADDING if ( pcCULeft && pcCULeft->getPredictionMode( uiPartLeft ) == MODE_INTRA ) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; #if MN_DC_PRED_FILTER m_bLeftFlagForDCFilt = false; #endif } pbValidFlags--; // opposite direction #else if ( !pcCULeft || pcCULeft->getPredictionMode( uiPartLeft ) != MODE_INTRA ) { bLeftFlag = false; #if MN_DC_PRED_FILTER m_bLeftFlagForDCFilt = false; #endif break; } #endif } #if REFERENCE_SAMPLE_PADDING return iNumIntra; #else return bLeftFlag; #endif } #if REFERENCE_SAMPLE_PADDING Int TComPattern::isAboveRightAvailableForCIP( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags ) #else Bool TComPattern::isAboveRightAvailableForCIP( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT ) #endif { const UInt uiNumUnitsInPU = g_auiZscanToRaster[uiPartIdxRT] - g_auiZscanToRaster[uiPartIdxLT] + 1; const UInt uiPuWidth = uiNumUnitsInPU * pcCU->getPic()->getMinCUWidth(); #if REFERENCE_SAMPLE_PADDING Bool *pbValidFlags = bValidFlags; Int iNumIntra = 0; #else Bool bAboveRightFlag = true; #endif for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ ) { UInt uiPartAboveRight; TComDataCU* pcCUAboveRight = pcCU->getPUAboveRightAdi( uiPartAboveRight, uiPuWidth, uiPartIdxRT, uiOffset, true, false ); #if REFERENCE_SAMPLE_PADDING if ( pcCUAboveRight && pcCUAboveRight->getPredictionMode( uiPartAboveRight ) == MODE_INTRA ) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; } pbValidFlags++; #else if ( !pcCUAboveRight || pcCUAboveRight->getPredictionMode( uiPartAboveRight ) != MODE_INTRA ) { bAboveRightFlag = false; break; } #endif } #if REFERENCE_SAMPLE_PADDING return iNumIntra; #else return bAboveRightFlag; #endif } #if REFERENCE_SAMPLE_PADDING Int TComPattern::isBelowLeftAvailableForCIP( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags ) #else Bool TComPattern::isBelowLeftAvailableForCIP( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB ) #endif { const UInt uiNumUnitsInPU = (g_auiZscanToRaster[uiPartIdxLB] - g_auiZscanToRaster[uiPartIdxLT]) / pcCU->getPic()->getNumPartInWidth() + 1; const UInt uiPuHeight = uiNumUnitsInPU * pcCU->getPic()->getMinCUHeight(); #if REFERENCE_SAMPLE_PADDING Bool *pbValidFlags = bValidFlags; Int iNumIntra = 0; #else Bool bBelowLeftFlag = true; #endif for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ ) { UInt uiPartBelowLeft; TComDataCU* pcCUBelowLeft = pcCU->getPUBelowLeftAdi( uiPartBelowLeft, uiPuHeight, uiPartIdxLB, uiOffset, true, false ); #if REFERENCE_SAMPLE_PADDING if ( pcCUBelowLeft && pcCUBelowLeft->getPredictionMode( uiPartBelowLeft ) == MODE_INTRA ) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; } pbValidFlags--; // opposite direction #else if ( !pcCUBelowLeft || pcCUBelowLeft->getPredictionMode( uiPartBelowLeft ) != MODE_INTRA ) { bBelowLeftFlag = false; break; } #endif } #if REFERENCE_SAMPLE_PADDING return iNumIntra; #else return bBelowLeftFlag; #endif } #endif //CONSTRAINED_INTRA_PRED