/* 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-2012, ITU/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 ITU/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" //! \ingroup TLibCommon //! \{ // ==================================================================================================================== // Tables // ==================================================================================================================== const UChar TComPattern::m_aucIntraFilter[5] = { 10, //4x4 7, //8x8 1, //16x16 0, //32x32 10, //64x64 }; // ==================================================================================================================== // 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 ) { m_iOffsetLeft = iOffsetLeft; m_iOffsetRight = iOffsetRight; m_iOffsetAbove = iOffsetAbove; m_iOffsetBottom = iOffsetBottom; m_iROIWidth = iRoiWidth; m_iROIHeight = iRoiHeight; UInt uiAbsZorderIdx = pcCU->getZorderIdxInCU() + uiAbsPartIdx; if ( iComp == 0 ) { m_iPatternStride = pcCU->getPic()->getStride(); m_piPatternOrigin = pcCU->getPic()->getPicYuvRec()->getLumaAddr(pcCU->getAddr(), uiAbsZorderIdx) - m_iOffsetAbove * m_iPatternStride - m_iOffsetLeft; } else { m_iPatternStride = pcCU->getPic()->getCStride(); if ( iComp == 1 ) { m_piPatternOrigin = pcCU->getPic()->getPicYuvRec()->getCbAddr(pcCU->getAddr(), uiAbsZorderIdx) - m_iOffsetAbove * m_iPatternStride - m_iOffsetLeft; } else { m_piPatternOrigin = pcCU->getPic()->getPicYuvRec()->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 ) { 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()->getPicWidthInLumaSamples() ) { 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; } } } } 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 ); } Void TComPattern::initAdiPattern( TComDataCU* pcCU, UInt uiZorderIdxInPart, UInt uiPartDepth, Int* piAdiBuf, Int iOrgBufStride, Int iOrgBufHeight, Bool& bAbove, Bool& bLeft, Bool bLMmode ) { 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; Int iPicStride = pcCU->getPic()->getStride(); Int iUnitSize = 0; Int iNumUnitsInCu = 0; Int iTotalUnits = 0; Bool bNeighborFlags[4 * MAX_NUM_SPU_W + 1]; Int iNumIntraNeighbor = 0; UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB; pcCU->deriveLeftRightTopIdxAdi( uiPartIdxLT, uiPartIdxRT, uiZorderIdxInPart, uiPartDepth ); pcCU->deriveLeftBottomIdxAdi ( uiPartIdxLB, uiZorderIdxInPart, uiPartDepth ); iUnitSize = g_uiMaxCUWidth >> g_uiMaxCUDepth; iNumUnitsInCu = uiCuWidth / iUnitSize; iTotalUnits = (iNumUnitsInCu << 2) + 1; bNeighborFlags[iNumUnitsInCu*2] = isAboveLeftAvailable( pcCU, uiPartIdxLT ); iNumIntraNeighbor += (Int)(bNeighborFlags[iNumUnitsInCu*2]); iNumIntraNeighbor += isAboveAvailable ( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*2)+1 ); iNumIntraNeighbor += isAboveRightAvailable( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*3)+1 ); iNumIntraNeighbor += isLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+(iNumUnitsInCu*2)-1 ); iNumIntraNeighbor += isBelowLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+ iNumUnitsInCu -1 ); bAbove = true; bLeft = true; uiWidth=uiCuWidth2+1; uiHeight=uiCuHeight2+1; if (((uiWidth<<2)>iOrgBufStride)||((uiHeight<<2)>iOrgBufHeight)) { return; } piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getLumaAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiZorderIdxInPart); piAdiTemp = piAdiBuf; fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride, bLMmode); Int i; // generate filtered intra prediction samples Int iBufSize = uiCuHeight2 + uiCuWidth2 + 1; // left and left above border + above and above right border + top left corner = length of 3. filter buffer UInt uiWH = uiWidth * uiHeight; // number of elements in one buffer Int* piFilteredBuf1 = piAdiBuf + uiWH; // 1. filter buffer Int* piFilteredBuf2 = piFilteredBuf1 + uiWH; // 2. filter buffer Int* piFilterBuf = piFilteredBuf2 + uiWH; // buffer for 2. filtering (sequential) Int* piFilterBufN = piFilterBuf + iBufSize; // buffer for 1. filtering (sequential) Int l = 0; // left border from bottom to top for (i = 0; i < uiCuHeight2; i++) { piFilterBuf[l++] = piAdiTemp[uiWidth * (uiCuHeight2 - i)]; } // top left corner piFilterBuf[l++] = piAdiTemp[0]; // above border from left to right for (i=0; i < uiCuWidth2; i++) { piFilterBuf[l++] = piAdiTemp[1 + i]; } // 1. filtering with [1 2 1] piFilterBufN[0] = piFilterBuf[0]; piFilterBufN[iBufSize - 1] = piFilterBuf[iBufSize - 1]; for (i = 1; i < iBufSize - 1; i++) { piFilterBufN[i] = (piFilterBuf[i - 1] + 2 * piFilterBuf[i]+piFilterBuf[i + 1] + 2) >> 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++]; } } 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 iUnitSize = 0; Int iNumUnitsInCu = 0; Int iTotalUnits = 0; Bool bNeighborFlags[4 * MAX_NUM_SPU_W + 1]; Int iNumIntraNeighbor = 0; UInt uiPartIdxLT, uiPartIdxRT, uiPartIdxLB; pcCU->deriveLeftRightTopIdxAdi( uiPartIdxLT, uiPartIdxRT, uiZorderIdxInPart, uiPartDepth ); pcCU->deriveLeftBottomIdxAdi ( uiPartIdxLB, uiZorderIdxInPart, uiPartDepth ); iUnitSize = (g_uiMaxCUWidth >> g_uiMaxCUDepth) >> 1; // for chroma iNumUnitsInCu = (uiCuWidth / iUnitSize) >> 1; // for chroma iTotalUnits = (iNumUnitsInCu << 2) + 1; bNeighborFlags[iNumUnitsInCu*2] = isAboveLeftAvailable( pcCU, uiPartIdxLT ); iNumIntraNeighbor += (Int)(bNeighborFlags[iNumUnitsInCu*2]); iNumIntraNeighbor += isAboveAvailable ( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*2)+1 ); iNumIntraNeighbor += isAboveRightAvailable( pcCU, uiPartIdxLT, uiPartIdxRT, bNeighborFlags+(iNumUnitsInCu*3)+1 ); iNumIntraNeighbor += isLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+(iNumUnitsInCu*2)-1 ); iNumIntraNeighbor += isBelowLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, bNeighborFlags+ iNumUnitsInCu -1 ); bAbove = true; bLeft = true; 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; fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride); // get Cr pattern piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getCrAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiZorderIdxInPart); piAdiTemp = piAdiBuf+uiWidth*uiHeight; fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride); } Void TComPattern::fillReferenceSamples( TComDataCU* pcCU, Pel* piRoiOrigin, Int* piAdiTemp, Bool* bNeighborFlags, Int iNumIntraNeighbor, Int iUnitSize, Int iNumUnitsInCu, Int iTotalUnits, UInt uiCuWidth, UInt uiCuHeight, UInt uiWidth, UInt uiHeight, Int iPicStride, Bool bLMmode ) { Pel* piRoiTemp; Int i, j; Int iDCValue = ( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) ); if (iNumIntraNeighbor == 0) { // Fill border with DC value for (i=0; i= 2 && log2BlkSize < 7); Int diff = min(abs((Int) uiDirMode - HOR_IDX), abs((Int)uiDirMode - VER_IDX)); UChar ucFiltIdx = diff > m_aucIntraFilter[log2BlkSize - 2] ? 1 : 0; #if REMOVE_LMCHROMA if (uiDirMode == DC_IDX) #else if (uiDirMode == DC_IDX || uiDirMode == LM_CHROMA_IDX) #endif { ucFiltIdx = 0; //no smoothing for DC or LM chroma } assert( ucFiltIdx <= 1 ); Int width = 1 << log2BlkSize; Int height = 1 << log2BlkSize; piSrc = getAdiOrgBuf( width, height, piAdiBuf ); if ( ucFiltIdx ) { piSrc += (2 * width + 1) * (2 * height + 1); } return piSrc; } Bool TComPattern::isAboveLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT ) { Bool bAboveLeftFlag; UInt uiPartAboveLeft; TComDataCU* pcCUAboveLeft = pcCU->getPUAboveLeft( uiPartAboveLeft, uiPartIdxLT, true, false ); if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) { bAboveLeftFlag = ( pcCUAboveLeft && pcCUAboveLeft->getPredictionMode( uiPartAboveLeft ) == MODE_INTRA ); } else { bAboveLeftFlag = (pcCUAboveLeft ? true : false); } return bAboveLeftFlag; } Int TComPattern::isAboveAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags ) { const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT]; const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxRT]+1; const UInt uiIdxStep = 1; Bool *pbValidFlags = bValidFlags; Int iNumIntra = 0; for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep ) { UInt uiPartAbove; TComDataCU* pcCUAbove = pcCU->getPUAbove( uiPartAbove, g_auiRasterToZscan[uiRasterPart], true, false ); if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) { if ( pcCUAbove && pcCUAbove->getPredictionMode( uiPartAbove ) == MODE_INTRA ) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; } } else { if (pcCUAbove) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; } } pbValidFlags++; } return iNumIntra; } Int TComPattern::isLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags ) { const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT]; const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxLB]+1; const UInt uiIdxStep = pcCU->getPic()->getNumPartInWidth(); Bool *pbValidFlags = bValidFlags; Int iNumIntra = 0; for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep ) { UInt uiPartLeft; TComDataCU* pcCULeft = pcCU->getPULeft( uiPartLeft, g_auiRasterToZscan[uiRasterPart], true, false ); if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) { if ( pcCULeft && pcCULeft->getPredictionMode( uiPartLeft ) == MODE_INTRA ) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; } } else { if ( pcCULeft ) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; } } pbValidFlags--; // opposite direction } return iNumIntra; } Int TComPattern::isAboveRightAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags ) { const UInt uiNumUnitsInPU = g_auiZscanToRaster[uiPartIdxRT] - g_auiZscanToRaster[uiPartIdxLT] + 1; const UInt uiPuWidth = uiNumUnitsInPU * pcCU->getPic()->getMinCUWidth(); Bool *pbValidFlags = bValidFlags; Int iNumIntra = 0; for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ ) { UInt uiPartAboveRight; TComDataCU* pcCUAboveRight = pcCU->getPUAboveRightAdi( uiPartAboveRight, uiPuWidth, uiPartIdxRT, uiOffset, true, false ); if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) { if ( pcCUAboveRight && pcCUAboveRight->getPredictionMode( uiPartAboveRight ) == MODE_INTRA ) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; } } else { if ( pcCUAboveRight ) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; } } pbValidFlags++; } return iNumIntra; } Int TComPattern::isBelowLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags ) { const UInt uiNumUnitsInPU = (g_auiZscanToRaster[uiPartIdxLB] - g_auiZscanToRaster[uiPartIdxLT]) / pcCU->getPic()->getNumPartInWidth() + 1; const UInt uiPuHeight = uiNumUnitsInPU * pcCU->getPic()->getMinCUHeight(); Bool *pbValidFlags = bValidFlags; Int iNumIntra = 0; for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ ) { UInt uiPartBelowLeft; TComDataCU* pcCUBelowLeft = pcCU->getPUBelowLeftAdi( uiPartBelowLeft, uiPuHeight, uiPartIdxLB, uiOffset, true, false ); if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred()) { if ( pcCUBelowLeft && pcCUBelowLeft->getPredictionMode( uiPartBelowLeft ) == MODE_INTRA ) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; } } else { if ( pcCUBelowLeft ) { iNumIntra++; *pbValidFlags = true; } else { *pbValidFlags = false; } } pbValidFlags--; // opposite direction } return iNumIntra; } //! \}