/** Create non-deblocked filter information * \param pSliceStartAddress array for storing slice start addresses * \param numSlices number of slices in picture * \param sliceGranularityDepth slice granularity * \param bNDBFilterCrossSliceBoundary cross-slice-boundary in-loop filtering; true for "cross". * \param numTiles number of tiles in picture * \param bNDBFilterCrossTileBoundary cross-tile-boundary in-loop filtering; true for "cross". */ Void TComPic::createNonDBFilterInfo(std::vector<Int> sliceStartAddress, Int sliceGranularityDepth ,std::vector<Bool>* LFCrossSliceBoundary ,Int numTiles ,Bool bNDBFilterCrossTileBoundary) { UInt maxNumSUInLCU = getNumPartInCU(); UInt numLCUInPic = getNumCUsInFrame(); UInt picWidth = getSlice(0)->getSPS()->getPicWidthInLumaSamples(); UInt picHeight = getSlice(0)->getSPS()->getPicHeightInLumaSamples(); Int numLCUsInPicWidth = getFrameWidthInCU(); Int numLCUsInPicHeight= getFrameHeightInCU(); UInt maxNumSUInLCUWidth = getNumPartInWidth(); UInt maxNumSUInLCUHeight= getNumPartInHeight(); Int numSlices = (Int) sliceStartAddress.size() - 1; m_bIndependentSliceBoundaryForNDBFilter = false; if(numSlices > 1) { for(Int s=0; s< numSlices; s++) { if((*LFCrossSliceBoundary)[s] == false) { m_bIndependentSliceBoundaryForNDBFilter = true; } } } m_sliceGranularityForNDBFilter = sliceGranularityDepth; m_bIndependentTileBoundaryForNDBFilter = (bNDBFilterCrossTileBoundary)?(false) :((numTiles > 1)?(true):(false)); m_pbValidSlice = new Bool[numSlices]; for(Int s=0; s< numSlices; s++) { m_pbValidSlice[s] = true; } m_pSliceSUMap = new Int[maxNumSUInLCU * numLCUInPic]; //initialization for(UInt i=0; i< (maxNumSUInLCU * numLCUInPic); i++ ) { m_pSliceSUMap[i] = -1; } for( UInt CUAddr = 0; CUAddr < numLCUInPic ; CUAddr++ ) { TComDataCU* pcCU = getCU( CUAddr ); pcCU->setSliceSUMap(m_pSliceSUMap + (CUAddr* maxNumSUInLCU)); pcCU->getNDBFilterBlocks()->clear(); } m_vSliceCUDataLink.clear(); m_vSliceCUDataLink.resize(numSlices); UInt startAddr, endAddr, firstCUInStartLCU, startLCU, endLCU, lastCUInEndLCU, uiAddr; UInt LPelX, TPelY, LCUX, LCUY; UInt currSU; UInt startSU, endSU; for(Int s=0; s< numSlices; s++) { //1st step: decide the real start address startAddr = sliceStartAddress[s]; endAddr = sliceStartAddress[s+1] -1; startLCU = startAddr / maxNumSUInLCU; firstCUInStartLCU = startAddr % maxNumSUInLCU; endLCU = endAddr / maxNumSUInLCU; lastCUInEndLCU = endAddr % maxNumSUInLCU; uiAddr = m_apcPicSym->getCUOrderMap(startLCU); LCUX = getCU(uiAddr)->getCUPelX(); LCUY = getCU(uiAddr)->getCUPelY(); LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[firstCUInStartLCU] ]; TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[firstCUInStartLCU] ]; currSU = firstCUInStartLCU; Bool bMoveToNextLCU = false; Bool bSliceInOneLCU = (startLCU == endLCU); while(!( LPelX < picWidth ) || !( TPelY < picHeight )) { currSU ++; if(bSliceInOneLCU) { if(currSU > lastCUInEndLCU) { m_pbValidSlice[s] = false; break; } } if(currSU >= maxNumSUInLCU ) { bMoveToNextLCU = true; break; } LPelX = LCUX + g_auiRasterToPelX[ g_auiZscanToRaster[currSU] ]; TPelY = LCUY + g_auiRasterToPelY[ g_auiZscanToRaster[currSU] ]; } if(!m_pbValidSlice[s]) { continue; } if(currSU != firstCUInStartLCU) { if(!bMoveToNextLCU) { firstCUInStartLCU = currSU; } else { startLCU++; firstCUInStartLCU = 0; assert( startLCU < getNumCUsInFrame()); } assert(startLCU*maxNumSUInLCU + firstCUInStartLCU < endAddr); } //2nd step: assign NonDBFilterInfo to each processing block for(UInt i= startLCU; i <= endLCU; i++) { startSU = (i == startLCU)?(firstCUInStartLCU):(0); endSU = (i == endLCU )?(lastCUInEndLCU ):(maxNumSUInLCU -1); uiAddr = m_apcPicSym->getCUOrderMap(i); Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr); TComDataCU* pcCU = getCU(uiAddr); m_vSliceCUDataLink[s].push_back(pcCU); createNonDBFilterInfoLCU(iTileID, s, pcCU, startSU, endSU, m_sliceGranularityForNDBFilter, picWidth, picHeight); } } //step 3: border availability for(Int s=0; s< numSlices; s++) { if(!m_pbValidSlice[s]) { continue; } for(Int i=0; i< m_vSliceCUDataLink[s].size(); i++) { TComDataCU* pcCU = m_vSliceCUDataLink[s][i]; uiAddr = pcCU->getAddr(); if(pcCU->getPic()==0) { continue; } Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr); Bool bTopTileBoundary = false, bDownTileBoundary= false, bLeftTileBoundary= false, bRightTileBoundary= false; if(m_bIndependentTileBoundaryForNDBFilter) { //left if( uiAddr % numLCUsInPicWidth != 0) { bLeftTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr -1) != iTileID )?true:false; } //right if( (uiAddr % numLCUsInPicWidth) != (numLCUsInPicWidth -1) ) { bRightTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr +1) != iTileID)?true:false; } //top if( uiAddr >= numLCUsInPicWidth) { bTopTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr - numLCUsInPicWidth) != iTileID )?true:false; } //down if( uiAddr + numLCUsInPicWidth < numLCUInPic ) { bDownTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr + numLCUsInPicWidth) != iTileID)?true:false; } } pcCU->setNDBFilterBlockBorderAvailability(numLCUsInPicWidth, numLCUsInPicHeight, maxNumSUInLCUWidth, maxNumSUInLCUHeight,picWidth, picHeight , *LFCrossSliceBoundary ,bTopTileBoundary, bDownTileBoundary, bLeftTileBoundary, bRightTileBoundary ,m_bIndependentTileBoundaryForNDBFilter); } } if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter) { m_pNDBFilterYuvTmp = new TComPicYuv(); m_pNDBFilterYuvTmp->create(picWidth, picHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth); } }
Void TComPic::createNonDBFilterInfo(UInt* puiSliceStartAddress, Int iNumSlices, Int iSliceGranularityDepth ,Bool bNDBFilterCrossSliceBoundary ,Int iNumTiles ,Bool bNDBFilterCrossTileBoundary) { UInt uiMaxNumSUInLCU = getNumPartInCU(); UInt uiNumLCUInPic = getNumCUsInFrame(); UInt uiPicWidth = getCU(0)->getSlice()->getSPS()->getWidth(); UInt uiPicHeight = getCU(0)->getSlice()->getSPS()->getHeight(); Int iNumLCUsInPicWidth = getFrameWidthInCU(); Int iNumLCUsInPicHeight= getFrameHeightInCU(); UInt uiMaxNumSUInLCUWidth = getNumPartInWidth(); UInt uiMAxNumSUInLCUHeight= getNumPartInHeight(); m_bIndependentSliceBoundaryForNDBFilter = (bNDBFilterCrossSliceBoundary)?(false):((iNumSlices > 1)?(true):(false)) ; m_iSliceGranularityForNDBFilter = iSliceGranularityDepth; m_bIndependentTileBoundaryForNDBFilter = (bNDBFilterCrossTileBoundary)?(false) :((iNumTiles > 1)?(true):(false)); m_pbValidSlice = new Bool[iNumSlices]; for(Int s=0; s< iNumSlices; s++) { m_pbValidSlice[s] = true; } if( puiSliceStartAddress == NULL || (iNumSlices == 1 && iNumTiles == 1) ) { return; } m_piSliceSUMap = new Int[uiMaxNumSUInLCU * uiNumLCUInPic]; //initialization for(UInt i=0; i< (uiMaxNumSUInLCU * uiNumLCUInPic); i++ ) { m_piSliceSUMap[i] = -1; } for( UInt uiCUAddr = 0; uiCUAddr < uiNumLCUInPic ; uiCUAddr++ ) { TComDataCU* pcCU = getCU( uiCUAddr ); pcCU->setSliceSUMap(m_piSliceSUMap + (uiCUAddr* uiMaxNumSUInLCU)); pcCU->getNDBFilterBlocks()->clear(); } m_vSliceCUDataLink.clear(); m_vSliceCUDataLink.resize(iNumSlices); UInt uiStartAddr, uiEndAddr, uiFirstCUInStartLCU, uiStartLCU, uiEndLCU, uiLastCUInEndLCU, uiAddr; UInt uiLPelX, uiTPelY, uiLCUX, uiLCUY; UInt uiCurrSU; UInt uiStartSU, uiEndSU; for(Int s=0; s< iNumSlices; s++) { //1st step: decide the real start address #if FINE_GRANULARITY_SLICES uiStartAddr = puiSliceStartAddress[s]; uiEndAddr = puiSliceStartAddress[s+1] -1; #else uiStartAddr = (puiSliceStartAddress[s]*uiMaxNumSUInLCU); uiEndAddr = (puiSliceStartAddress[s+1]*uiMaxNumSUInLCU) -1; #endif uiStartLCU = uiStartAddr / uiMaxNumSUInLCU; uiFirstCUInStartLCU = uiStartAddr % uiMaxNumSUInLCU; uiEndLCU = uiEndAddr / uiMaxNumSUInLCU; uiLastCUInEndLCU = uiEndAddr % uiMaxNumSUInLCU; #if TILES uiAddr = m_apcPicSym->getCUOrderMap(uiStartLCU); #else uiAddr = uiStartLCU; #endif uiLCUX = getCU(uiAddr)->getCUPelX(); uiLCUY = getCU(uiAddr)->getCUPelY(); uiLPelX = uiLCUX + g_auiRasterToPelX[ g_auiZscanToRaster[uiFirstCUInStartLCU] ]; uiTPelY = uiLCUY + g_auiRasterToPelY[ g_auiZscanToRaster[uiFirstCUInStartLCU] ]; uiCurrSU = uiFirstCUInStartLCU; Bool bMoveToNextLCU = false; Bool bSliceInOneLCU = (uiStartLCU == uiEndLCU); while(!( uiLPelX < uiPicWidth ) || !( uiTPelY < uiPicHeight )) { uiCurrSU ++; if(bSliceInOneLCU) { if(uiCurrSU > uiLastCUInEndLCU) { m_pbValidSlice[s] = false; break; } } if(uiCurrSU >= uiMaxNumSUInLCU ) { bMoveToNextLCU = true; break; } uiLPelX = uiLCUX + g_auiRasterToPelX[ g_auiZscanToRaster[uiCurrSU] ]; uiTPelY = uiLCUY + g_auiRasterToPelY[ g_auiZscanToRaster[uiCurrSU] ]; } if(!m_pbValidSlice[s]) { continue; } if(uiCurrSU != uiFirstCUInStartLCU) { if(!bMoveToNextLCU) { uiFirstCUInStartLCU = uiCurrSU; } else { uiStartLCU++; uiFirstCUInStartLCU = 0; assert( uiStartLCU < getNumCUsInFrame()); } assert(uiStartLCU*uiMaxNumSUInLCU + uiFirstCUInStartLCU < uiEndAddr); } //2nd step: assign NonDBFilterInfo to each processing block for(UInt i= uiStartLCU; i <= uiEndLCU; i++) { uiStartSU = (i == uiStartLCU)?(uiFirstCUInStartLCU):(0); uiEndSU = (i == uiEndLCU )?(uiLastCUInEndLCU ):(uiMaxNumSUInLCU -1); #if TILES uiAddr = m_apcPicSym->getCUOrderMap(i); Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr); #else uiAddr = i; #endif TComDataCU* pcCU = getCU(uiAddr); m_vSliceCUDataLink[s].push_back(pcCU); #if TILES createNonDBFilterInfoLCU(iTileID, s, pcCU, uiStartSU, uiEndSU, m_iSliceGranularityForNDBFilter, uiPicWidth, uiPicHeight); #else createNonDBFilterInfoLCU(s, pcCU, uiStartSU, uiEndSU, m_iSliceGranularityForNDBFilter, uiPicWidth, uiPicHeight); #endif } } //step 3: border availability for(Int s=0; s< iNumSlices; s++) { if(!m_pbValidSlice[s]) { continue; } for(Int i=0; i< m_vSliceCUDataLink[s].size(); i++) { TComDataCU* pcCU = m_vSliceCUDataLink[s][i]; uiAddr = pcCU->getAddr(); Int iTileID= m_apcPicSym->getTileIdxMap(uiAddr); Bool bTopTileBoundary = false, bDownTileBoundary= false, bLeftTileBoundary= false, bRightTileBoundary= false; if(m_bIndependentTileBoundaryForNDBFilter) { //left if( uiAddr % iNumLCUsInPicWidth != 0) { bLeftTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr -1) != iTileID )?true:false; } //right if( (uiAddr % iNumLCUsInPicWidth) != (iNumLCUsInPicWidth -1) ) { bRightTileBoundary = ( m_apcPicSym->getTileIdxMap(uiAddr +1) != iTileID)?true:false; } //top if( uiAddr >= iNumLCUsInPicWidth) { bTopTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr - iNumLCUsInPicWidth) != iTileID )?true:false; } //down if( uiAddr + iNumLCUsInPicWidth < uiNumLCUInPic ) { bDownTileBoundary = (m_apcPicSym->getTileIdxMap(uiAddr + iNumLCUsInPicWidth) != iTileID)?true:false; } } pcCU->setNDBFilterBlockBorderAvailability(iNumLCUsInPicWidth, iNumLCUsInPicHeight, uiMaxNumSUInLCUWidth, uiMAxNumSUInLCUHeight,uiPicWidth, uiPicHeight ,m_bIndependentSliceBoundaryForNDBFilter ,bTopTileBoundary, bDownTileBoundary, bLeftTileBoundary, bRightTileBoundary ,m_bIndependentTileBoundaryForNDBFilter); } } if( m_bIndependentSliceBoundaryForNDBFilter || m_bIndependentTileBoundaryForNDBFilter) { m_pcNDBFilterYuvTmp = new TComPicYuv(); m_pcNDBFilterYuvTmp->create(uiPicWidth, uiPicHeight, g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth); } }