/** \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, Bool bPrdDepthMap ) { m_iOffsetLeft = iOffsetLeft; m_iOffsetRight = iOffsetRight; m_iOffsetAbove = iOffsetAbove; m_iOffsetBottom = iOffsetBottom; m_iROIWidth = iRoiWidth; m_iROIHeight = iRoiHeight; UInt uiAbsZorderIdx = pcCU->getZorderIdxInCU() + uiAbsPartIdx; TComPicYuv* pcPic = ( bPrdDepthMap ? pcCU->getPic()->getPredDepthMap() : pcCU->getPic()->getPicYuvRec() ); if ( iComp == 0 ) { m_iPatternStride = pcCU->getPic()->getStride(); m_piPatternOrigin = pcPic->getLumaAddr(pcCU->getAddr(), uiAbsZorderIdx) - m_iOffsetAbove * m_iPatternStride - m_iOffsetLeft; } else { m_iPatternStride = pcCU->getPic()->getCStride(); 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, Bool bPrdDepthMap ) { 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 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 ); } Void TComPattern::initAdiPattern( TComDataCU* pcCU, UInt uiZorderIdxInPart, UInt uiPartDepth, Int* piAdiBuf, Int iOrgBufStride, Int iOrgBufHeight, Bool& bAbove, Bool& bLeft, Bool bPrdDepthMap ) { 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 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 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; if( bPrdDepthMap ) { piRoiOrigin = pcCU->getPic()->getPredDepthMap()->getLumaAddr( pcCU->getAddr(), pcCU->getZorderIdxInCU() + uiZorderIdxInPart ); #if REFERENCE_SAMPLE_PADDING #else iDCValue = PDM_UNDEFINED_DEPTH; #endif } #if REFERENCE_SAMPLE_PADDING fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride, bPrdDepthMap ); 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 fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride, false ); #else // REFERENCE_SAMPLE_PADDING for (i=0;igetPic()->getPicYuvRec()->getCrAddr(pcCU->getAddr(), pcCU->getZorderIdxInCU()+uiZorderIdxInPart); piAdiTemp = piAdiBuf+uiWidth*uiHeight; #if REFERENCE_SAMPLE_PADDING fillReferenceSamples ( pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitSize, iNumUnitsInCu, iTotalUnits, uiCuWidth, uiCuHeight, uiWidth, uiHeight, iPicStride, false ); 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