Ignore:
Timestamp:
2 Feb 2014, 04:51:29 (11 years ago)
Author:
seregin
Message:

update to HM-13.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/SHM-5.0-dev/source/Lib/TLibCommon/TComSampleAdaptiveOffset.cpp

    r540 r593  
    44 * granted under this license. 
    55 *
    6  * Copyright (c) 2010-2013, ITU/ISO/IEC
     6 * Copyright (c) 2010-2014, ITU/ISO/IEC
    77 * All rights reserved.
    88 *
     
    4444//! \ingroup TLibCommon
    4545//! \{
    46 #if HM_CLEANUP_SAO
    4746UInt g_saoMaxOffsetQVal[NUM_SAO_COMPONENTS];
    4847
     
    698697  return pBuf;
    699698}
    700 #else
    701 
    702 SAOParam::~SAOParam()
    703 {
    704   for (Int i = 0 ; i<3; i++)
    705   {
    706     if (psSaoPart[i])
    707     {
    708       delete [] psSaoPart[i];
    709     }
    710   }
    711 }
    712 
    713 // ====================================================================================================================
    714 // Tables
    715 // ====================================================================================================================
    716 
    717 TComSampleAdaptiveOffset::TComSampleAdaptiveOffset()
    718 {
    719   m_pClipTable = NULL;
    720   m_pClipTableBase = NULL;
    721   m_pChromaClipTable = NULL;
    722   m_pChromaClipTableBase = NULL;
    723   m_iOffsetBo = NULL;
    724   m_iChromaOffsetBo = NULL;
    725   m_lumaTableBo = NULL;
    726   m_chromaTableBo = NULL;
    727   m_iUpBuff1 = NULL;
    728   m_iUpBuff2 = NULL;
    729   m_iUpBufft = NULL;
    730   ipSwap = NULL;
    731 
    732   m_pTmpU1 = NULL;
    733   m_pTmpU2 = NULL;
    734   m_pTmpL1 = NULL;
    735   m_pTmpL2 = NULL;
    736 }
    737 
    738 TComSampleAdaptiveOffset::~TComSampleAdaptiveOffset()
    739 {
    740 
    741 }
    742 
    743 const Int TComSampleAdaptiveOffset::m_aiNumCulPartsLevel[5] =
    744 {
    745   1,   //level 0
    746   5,   //level 1
    747   21,  //level 2
    748   85,  //level 3
    749   341, //level 4
    750 };
    751 
    752 const UInt TComSampleAdaptiveOffset::m_auiEoTable[9] =
    753 {
    754   1, //0   
    755   2, //1   
    756   0, //2
    757   3, //3
    758   4, //4
    759   0, //5 
    760   0, //6 
    761   0, //7
    762   0
    763 };
    764 
    765 const Int TComSampleAdaptiveOffset::m_iNumClass[MAX_NUM_SAO_TYPE] =
    766 {
    767   SAO_EO_LEN,
    768   SAO_EO_LEN,
    769   SAO_EO_LEN,
    770   SAO_EO_LEN,
    771   SAO_BO_LEN
    772 };
    773 
    774 const UInt TComSampleAdaptiveOffset::m_uiMaxDepth = SAO_MAX_DEPTH;
    775 
    776 
    777 /** convert Level Row Col to Idx
    778  * \param   level,  row,  col
    779  */
    780 Int  TComSampleAdaptiveOffset::convertLevelRowCol2Idx(Int level, Int row, Int col)
    781 {
    782   Int idx;
    783   if (level == 0)
    784   {
    785     idx = 0;
    786   }
    787   else if (level == 1)
    788   {
    789     idx = 1 + row*2 + col;
    790   }
    791   else if (level == 2)
    792   {
    793     idx = 5 + row*4 + col;
    794   }
    795   else if (level == 3)
    796   {
    797     idx = 21 + row*8 + col;
    798   }
    799   else // (level == 4)
    800   {
    801     idx = 85 + row*16 + col;
    802   }
    803   return idx;
    804 }
    805 
    806 /** create SampleAdaptiveOffset memory.
    807  * \param
    808  */
    809 Void TComSampleAdaptiveOffset::create( UInt uiSourceWidth, UInt uiSourceHeight, UInt uiMaxCUWidth, UInt uiMaxCUHeight )
    810 {
    811   m_iPicWidth  = uiSourceWidth;
    812   m_iPicHeight = uiSourceHeight;
    813 
    814   m_uiMaxCUWidth  = uiMaxCUWidth;
    815   m_uiMaxCUHeight = uiMaxCUHeight;
    816 
    817   m_iNumCuInWidth  = m_iPicWidth / m_uiMaxCUWidth;
    818   m_iNumCuInWidth += ( m_iPicWidth % m_uiMaxCUWidth ) ? 1 : 0;
    819 
    820   m_iNumCuInHeight  = m_iPicHeight / m_uiMaxCUHeight;
    821   m_iNumCuInHeight += ( m_iPicHeight % m_uiMaxCUHeight ) ? 1 : 0;
    822 
    823   Int iMaxSplitLevelHeight = (Int)(logf((Float)m_iNumCuInHeight)/logf(2.0));
    824   Int iMaxSplitLevelWidth  = (Int)(logf((Float)m_iNumCuInWidth )/logf(2.0));
    825 
    826   m_uiMaxSplitLevel = (iMaxSplitLevelHeight < iMaxSplitLevelWidth)?(iMaxSplitLevelHeight):(iMaxSplitLevelWidth);
    827   m_uiMaxSplitLevel = (m_uiMaxSplitLevel< m_uiMaxDepth)?(m_uiMaxSplitLevel):(m_uiMaxDepth);
    828   /* various structures are overloaded to store per component data.
    829    * m_iNumTotalParts must allow for sufficient storage in any allocated arrays */
    830   m_iNumTotalParts  = max(3,m_aiNumCulPartsLevel[m_uiMaxSplitLevel]);
    831 
    832   UInt uiPixelRangeY = 1 << g_bitDepthY;
    833   UInt uiBoRangeShiftY = g_bitDepthY - SAO_BO_BITS;
    834 
    835   m_lumaTableBo = new Pel [uiPixelRangeY];
    836   for (Int k2=0; k2<uiPixelRangeY; k2++)
    837   {
    838     m_lumaTableBo[k2] = 1 + (k2>>uiBoRangeShiftY);
    839   }
    840 
    841   UInt uiPixelRangeC = 1 << g_bitDepthC;
    842   UInt uiBoRangeShiftC = g_bitDepthC - SAO_BO_BITS;
    843 
    844   m_chromaTableBo = new Pel [uiPixelRangeC];
    845   for (Int k2=0; k2<uiPixelRangeC; k2++)
    846   {
    847     m_chromaTableBo[k2] = 1 + (k2>>uiBoRangeShiftC);
    848   }
    849 
    850   m_iUpBuff1 = new Int[m_iPicWidth+2];
    851   m_iUpBuff2 = new Int[m_iPicWidth+2];
    852   m_iUpBufft = new Int[m_iPicWidth+2];
    853 
    854   m_iUpBuff1++;
    855   m_iUpBuff2++;
    856   m_iUpBufft++;
    857   Pel i;
    858 
    859   UInt uiMaxY  = (1 << g_bitDepthY) - 1;;
    860   UInt uiMinY  = 0;
    861 
    862   Int iCRangeExt = uiMaxY>>1;
    863 
    864   m_pClipTableBase = new Pel[uiMaxY+2*iCRangeExt];
    865   m_iOffsetBo      = new Int[uiMaxY+2*iCRangeExt];
    866 
    867   for(i=0;i<(uiMinY+iCRangeExt);i++)
    868   {
    869     m_pClipTableBase[i] = uiMinY;
    870   }
    871 
    872   for(i=uiMinY+iCRangeExt;i<(uiMaxY+  iCRangeExt);i++)
    873   {
    874     m_pClipTableBase[i] = i-iCRangeExt;
    875   }
    876 
    877   for(i=uiMaxY+iCRangeExt;i<(uiMaxY+2*iCRangeExt);i++)
    878   {
    879     m_pClipTableBase[i] = uiMaxY;
    880   }
    881 
    882   m_pClipTable = &(m_pClipTableBase[iCRangeExt]);
    883 
    884   UInt uiMaxC  = (1 << g_bitDepthC) - 1;
    885   UInt uiMinC  = 0;
    886 
    887   Int iCRangeExtC = uiMaxC>>1;
    888 
    889   m_pChromaClipTableBase = new Pel[uiMaxC+2*iCRangeExtC];
    890   m_iChromaOffsetBo      = new Int[uiMaxC+2*iCRangeExtC];
    891 
    892   for(i=0;i<(uiMinC+iCRangeExtC);i++)
    893   {
    894     m_pChromaClipTableBase[i] = uiMinC;
    895   }
    896 
    897   for(i=uiMinC+iCRangeExtC;i<(uiMaxC+  iCRangeExtC);i++)
    898   {
    899     m_pChromaClipTableBase[i] = i-iCRangeExtC;
    900   }
    901 
    902   for(i=uiMaxC+iCRangeExtC;i<(uiMaxC+2*iCRangeExtC);i++)
    903   {
    904     m_pChromaClipTableBase[i] = uiMaxC;
    905   }
    906 
    907   m_pChromaClipTable = &(m_pChromaClipTableBase[iCRangeExtC]);
    908 
    909   m_pTmpL1 = new Pel [m_uiMaxCUHeight+1];
    910   m_pTmpL2 = new Pel [m_uiMaxCUHeight+1];
    911   m_pTmpU1 = new Pel [m_iPicWidth];
    912   m_pTmpU2 = new Pel [m_iPicWidth];
    913 }
    914 
    915 /** destroy SampleAdaptiveOffset memory.
    916  * \param
    917  */
    918 Void TComSampleAdaptiveOffset::destroy()
    919 {
    920   if (m_pClipTableBase)
    921   {
    922     delete [] m_pClipTableBase; m_pClipTableBase = NULL;
    923   }
    924   if (m_iOffsetBo)
    925   {
    926     delete [] m_iOffsetBo; m_iOffsetBo = NULL;
    927   }
    928   if (m_lumaTableBo)
    929   {
    930     delete[] m_lumaTableBo; m_lumaTableBo = NULL;
    931   }
    932 
    933   if (m_pChromaClipTableBase)
    934   {
    935     delete [] m_pChromaClipTableBase; m_pChromaClipTableBase = NULL;
    936   }
    937   if (m_iChromaOffsetBo)
    938   {
    939     delete [] m_iChromaOffsetBo; m_iChromaOffsetBo = NULL;
    940   }
    941   if (m_chromaTableBo)
    942   {
    943     delete[] m_chromaTableBo; m_chromaTableBo = NULL;
    944   }
    945 
    946   if (m_iUpBuff1)
    947   {
    948     m_iUpBuff1--;
    949     delete [] m_iUpBuff1; m_iUpBuff1 = NULL;
    950   }
    951   if (m_iUpBuff2)
    952   {
    953     m_iUpBuff2--;
    954     delete [] m_iUpBuff2; m_iUpBuff2 = NULL;
    955   }
    956   if (m_iUpBufft)
    957   {
    958     m_iUpBufft--;
    959     delete [] m_iUpBufft; m_iUpBufft = NULL;
    960   }
    961   if (m_pTmpL1)
    962   {
    963     delete [] m_pTmpL1; m_pTmpL1 = NULL;
    964   }
    965   if (m_pTmpL2)
    966   {
    967     delete [] m_pTmpL2; m_pTmpL2 = NULL;
    968   }
    969   if (m_pTmpU1)
    970   {
    971     delete [] m_pTmpU1; m_pTmpU1 = NULL;
    972   }
    973   if (m_pTmpU2)
    974   {
    975     delete [] m_pTmpU2; m_pTmpU2 = NULL;
    976   }
    977 }
    978 
    979 /** allocate memory for SAO parameters
    980  * \param    *pcSaoParam
    981  */
    982 Void TComSampleAdaptiveOffset::allocSaoParam(SAOParam *pcSaoParam)
    983 {
    984   pcSaoParam->iMaxSplitLevel = m_uiMaxSplitLevel;
    985   pcSaoParam->psSaoPart[0] = new SAOQTPart[ m_aiNumCulPartsLevel[pcSaoParam->iMaxSplitLevel] ];
    986   initSAOParam(pcSaoParam, 0, 0, 0, -1, 0, m_iNumCuInWidth-1,  0, m_iNumCuInHeight-1,0);
    987   pcSaoParam->psSaoPart[1] = new SAOQTPart[ m_aiNumCulPartsLevel[pcSaoParam->iMaxSplitLevel] ];
    988   pcSaoParam->psSaoPart[2] = new SAOQTPart[ m_aiNumCulPartsLevel[pcSaoParam->iMaxSplitLevel] ];
    989   initSAOParam(pcSaoParam, 0, 0, 0, -1, 0, m_iNumCuInWidth-1,  0, m_iNumCuInHeight-1,1);
    990   initSAOParam(pcSaoParam, 0, 0, 0, -1, 0, m_iNumCuInWidth-1,  0, m_iNumCuInHeight-1,2);
    991   pcSaoParam->numCuInWidth  = m_iNumCuInWidth;
    992   pcSaoParam->numCuInHeight = m_iNumCuInHeight;
    993   pcSaoParam->saoLcuParam[0] = new SaoLcuParam [m_iNumCuInHeight*m_iNumCuInWidth];
    994   pcSaoParam->saoLcuParam[1] = new SaoLcuParam [m_iNumCuInHeight*m_iNumCuInWidth];
    995   pcSaoParam->saoLcuParam[2] = new SaoLcuParam [m_iNumCuInHeight*m_iNumCuInWidth];
    996 }
    997 
    998 /** initialize SAO parameters
    999  * \param    *pcSaoParam,  iPartLevel,  iPartRow,  iPartCol,  iParentPartIdx,  StartCUX,  EndCUX,  StartCUY,  EndCUY,  iYCbCr
    1000  */
    1001 Void TComSampleAdaptiveOffset::initSAOParam(SAOParam *pcSaoParam, Int iPartLevel, Int iPartRow, Int iPartCol, Int iParentPartIdx, Int StartCUX, Int EndCUX, Int StartCUY, Int EndCUY, Int iYCbCr)
    1002 {
    1003   Int j;
    1004   Int iPartIdx = convertLevelRowCol2Idx(iPartLevel, iPartRow, iPartCol);
    1005 
    1006   SAOQTPart* pSaoPart;
    1007 
    1008   pSaoPart = &(pcSaoParam->psSaoPart[iYCbCr][iPartIdx]);
    1009 
    1010   pSaoPart->PartIdx   = iPartIdx;
    1011   pSaoPart->PartLevel = iPartLevel;
    1012   pSaoPart->PartRow   = iPartRow;
    1013   pSaoPart->PartCol   = iPartCol;
    1014 
    1015   pSaoPart->StartCUX  = StartCUX;
    1016   pSaoPart->EndCUX    = EndCUX;
    1017   pSaoPart->StartCUY  = StartCUY;
    1018   pSaoPart->EndCUY    = EndCUY;
    1019 
    1020   pSaoPart->UpPartIdx = iParentPartIdx;
    1021   pSaoPart->iBestType   = -1;
    1022   pSaoPart->iLength     =  0;
    1023 
    1024   pSaoPart->subTypeIdx = 0;
    1025 
    1026   for (j=0;j<MAX_NUM_SAO_OFFSETS;j++)
    1027   {
    1028     pSaoPart->iOffset[j] = 0;
    1029   }
    1030 
    1031   if(pSaoPart->PartLevel != m_uiMaxSplitLevel)
    1032   {
    1033     Int DownLevel    = (iPartLevel+1 );
    1034     Int DownRowStart = (iPartRow << 1);
    1035     Int DownColStart = (iPartCol << 1);
    1036 
    1037     Int iDownRowIdx, iDownColIdx;
    1038     Int NumCUWidth,  NumCUHeight;
    1039     Int NumCULeft;
    1040     Int NumCUTop;
    1041 
    1042     Int DownStartCUX, DownStartCUY;
    1043     Int DownEndCUX, DownEndCUY;
    1044 
    1045     NumCUWidth  = EndCUX - StartCUX +1;
    1046     NumCUHeight = EndCUY - StartCUY +1;
    1047     NumCULeft   = (NumCUWidth  >> 1);
    1048     NumCUTop    = (NumCUHeight >> 1);
    1049 
    1050     DownStartCUX= StartCUX;
    1051     DownEndCUX  = DownStartCUX + NumCULeft - 1;
    1052     DownStartCUY= StartCUY;
    1053     DownEndCUY  = DownStartCUY + NumCUTop  - 1;
    1054     iDownRowIdx = DownRowStart + 0;
    1055     iDownColIdx = DownColStart + 0;
    1056 
    1057     pSaoPart->DownPartsIdx[0]= convertLevelRowCol2Idx(DownLevel, iDownRowIdx, iDownColIdx);
    1058 
    1059     initSAOParam(pcSaoParam, DownLevel, iDownRowIdx, iDownColIdx, iPartIdx, DownStartCUX, DownEndCUX, DownStartCUY, DownEndCUY, iYCbCr);
    1060 
    1061     DownStartCUX = StartCUX + NumCULeft;
    1062     DownEndCUX   = EndCUX;
    1063     DownStartCUY = StartCUY;
    1064     DownEndCUY   = DownStartCUY + NumCUTop -1;
    1065     iDownRowIdx  = DownRowStart + 0;
    1066     iDownColIdx  = DownColStart + 1;
    1067 
    1068     pSaoPart->DownPartsIdx[1] = convertLevelRowCol2Idx(DownLevel, iDownRowIdx, iDownColIdx);
    1069 
    1070     initSAOParam(pcSaoParam, DownLevel, iDownRowIdx, iDownColIdx, iPartIdx,  DownStartCUX, DownEndCUX, DownStartCUY, DownEndCUY, iYCbCr);
    1071 
    1072     DownStartCUX = StartCUX;
    1073     DownEndCUX   = DownStartCUX + NumCULeft -1;
    1074     DownStartCUY = StartCUY + NumCUTop;
    1075     DownEndCUY   = EndCUY;
    1076     iDownRowIdx  = DownRowStart + 1;
    1077     iDownColIdx  = DownColStart + 0;
    1078 
    1079     pSaoPart->DownPartsIdx[2] = convertLevelRowCol2Idx(DownLevel, iDownRowIdx, iDownColIdx);
    1080 
    1081     initSAOParam(pcSaoParam, DownLevel, iDownRowIdx, iDownColIdx, iPartIdx, DownStartCUX, DownEndCUX, DownStartCUY, DownEndCUY, iYCbCr);
    1082 
    1083     DownStartCUX = StartCUX+ NumCULeft;
    1084     DownEndCUX   = EndCUX;
    1085     DownStartCUY = StartCUY + NumCUTop;
    1086     DownEndCUY   = EndCUY;
    1087     iDownRowIdx  = DownRowStart + 1;
    1088     iDownColIdx  = DownColStart + 1;
    1089 
    1090     pSaoPart->DownPartsIdx[3] = convertLevelRowCol2Idx(DownLevel, iDownRowIdx, iDownColIdx);
    1091 
    1092     initSAOParam(pcSaoParam, DownLevel, iDownRowIdx, iDownColIdx, iPartIdx,DownStartCUX, DownEndCUX, DownStartCUY, DownEndCUY, iYCbCr);
    1093   }
    1094   else
    1095   {
    1096     pSaoPart->DownPartsIdx[0]=pSaoPart->DownPartsIdx[1]= pSaoPart->DownPartsIdx[2]= pSaoPart->DownPartsIdx[3]= -1;
    1097   }
    1098 }
    1099 
    1100 /** free memory of SAO parameters
    1101  * \param   pcSaoParam
    1102  */
    1103 Void TComSampleAdaptiveOffset::freeSaoParam(SAOParam *pcSaoParam)
    1104 {
    1105   delete [] pcSaoParam->psSaoPart[0];
    1106   delete [] pcSaoParam->psSaoPart[1];
    1107   delete [] pcSaoParam->psSaoPart[2];
    1108   pcSaoParam->psSaoPart[0] = 0;
    1109   pcSaoParam->psSaoPart[1] = 0;
    1110   pcSaoParam->psSaoPart[2] = 0;
    1111   if( pcSaoParam->saoLcuParam[0])
    1112   {
    1113     delete [] pcSaoParam->saoLcuParam[0]; pcSaoParam->saoLcuParam[0] = NULL;
    1114   }
    1115   if( pcSaoParam->saoLcuParam[1])
    1116   {
    1117     delete [] pcSaoParam->saoLcuParam[1]; pcSaoParam->saoLcuParam[1] = NULL;
    1118   }
    1119   if( pcSaoParam->saoLcuParam[2])
    1120   {
    1121     delete [] pcSaoParam->saoLcuParam[2]; pcSaoParam->saoLcuParam[2] = NULL;
    1122   }
    1123 }
    1124 
    1125 /** reset SAO parameters
    1126  * \param   pcSaoParam
    1127  */
    1128 Void TComSampleAdaptiveOffset::resetSAOParam(SAOParam *pcSaoParam)
    1129 {
    1130   Int iNumComponet = 3;
    1131   for(Int c=0; c<iNumComponet; c++)
    1132   {
    1133 if (c<2)
    1134   {
    1135     pcSaoParam->bSaoFlag[c] = 0;
    1136   }
    1137     for(Int i=0; i< m_aiNumCulPartsLevel[m_uiMaxSplitLevel]; i++)
    1138     {
    1139       pcSaoParam->psSaoPart[c][i].iBestType     = -1;
    1140       pcSaoParam->psSaoPart[c][i].iLength       =  0;
    1141       pcSaoParam->psSaoPart[c][i].bSplit        = false;
    1142       pcSaoParam->psSaoPart[c][i].bProcessed    = false;
    1143       pcSaoParam->psSaoPart[c][i].dMinCost      = MAX_DOUBLE;
    1144       pcSaoParam->psSaoPart[c][i].iMinDist      = MAX_INT;
    1145       pcSaoParam->psSaoPart[c][i].iMinRate      = MAX_INT;
    1146       pcSaoParam->psSaoPart[c][i].subTypeIdx    = 0;
    1147       for (Int j=0;j<MAX_NUM_SAO_OFFSETS;j++)
    1148       {
    1149         pcSaoParam->psSaoPart[c][i].iOffset[j] = 0;
    1150         pcSaoParam->psSaoPart[c][i].iOffset[j] = 0;
    1151         pcSaoParam->psSaoPart[c][i].iOffset[j] = 0;
    1152       }
    1153     }
    1154     pcSaoParam->oneUnitFlag[0]   = 0;
    1155     pcSaoParam->oneUnitFlag[1]   = 0;
    1156     pcSaoParam->oneUnitFlag[2]   = 0;
    1157     resetLcuPart(pcSaoParam->saoLcuParam[0]);
    1158     resetLcuPart(pcSaoParam->saoLcuParam[1]);
    1159     resetLcuPart(pcSaoParam->saoLcuParam[2]);
    1160   }
    1161 }
    1162 
    1163 /** get the sign of input variable
    1164  * \param   x
    1165  */
    1166 inline Int xSign(Int x)
    1167 {
    1168   return ((x >> 31) | ((Int)( (((UInt) -x)) >> 31)));
    1169 }
    1170 
    1171 /** initialize variables for SAO process
    1172  * \param  pcPic picture data pointer
    1173  */
    1174 Void TComSampleAdaptiveOffset::createPicSaoInfo(TComPic* pcPic)
    1175 {
    1176   m_pcPic   = pcPic;
    1177   m_bUseNIF = ( pcPic->getIndependentSliceBoundaryForNDBFilter() || pcPic->getIndependentTileBoundaryForNDBFilter() );
    1178   if(m_bUseNIF)
    1179   {
    1180     m_pcYuvTmp = pcPic->getYuvPicBufferForIndependentBoundaryProcessing();
    1181   }
    1182 }
    1183 
    1184 Void TComSampleAdaptiveOffset::destroyPicSaoInfo()
    1185 {
    1186 
    1187 }
    1188 
    1189 /** sample adaptive offset process for one LCU
    1190  * \param   iAddr, iSaoType, iYCbCr
    1191  */
    1192 Void TComSampleAdaptiveOffset::processSaoCu(Int iAddr, Int iSaoType, Int iYCbCr)
    1193 {
    1194   if(!m_bUseNIF)
    1195   {
    1196     processSaoCuOrg( iAddr, iSaoType, iYCbCr);
    1197   }
    1198   else
    1199   { 
    1200     Int  isChroma = (iYCbCr != 0)? 1:0;
    1201     Int  stride   = (iYCbCr != 0)?(m_pcPic->getCStride()):(m_pcPic->getStride());
    1202     Pel* pPicRest = getPicYuvAddr(m_pcPic->getPicYuvRec(), iYCbCr);
    1203     Pel* pPicDec  = getPicYuvAddr(m_pcYuvTmp, iYCbCr);
    1204 
    1205     std::vector<NDBFBlockInfo>& vFilterBlocks = *(m_pcPic->getCU(iAddr)->getNDBFilterBlocks());
    1206 
    1207     //variables
    1208     UInt  xPos, yPos, width, height;
    1209     Bool* pbBorderAvail;
    1210     UInt  posOffset;
    1211 
    1212     for(Int i=0; i< vFilterBlocks.size(); i++)
    1213     {
    1214       xPos        = vFilterBlocks[i].posX   >> isChroma;
    1215       yPos        = vFilterBlocks[i].posY   >> isChroma;
    1216       width       = vFilterBlocks[i].width  >> isChroma;
    1217       height      = vFilterBlocks[i].height >> isChroma;
    1218       pbBorderAvail = vFilterBlocks[i].isBorderAvailable;
    1219 
    1220       posOffset = (yPos* stride) + xPos;
    1221 
    1222       processSaoBlock(pPicDec+ posOffset, pPicRest+ posOffset, stride, iSaoType, width, height, pbBorderAvail, iYCbCr);
    1223     }
    1224   }
    1225 }
    1226 
    1227 /** Perform SAO for non-cross-slice or non-cross-tile process
    1228  * \param  pDec to-be-filtered block buffer pointer
    1229  * \param  pRest filtered block buffer pointer
    1230  * \param  stride picture buffer stride
    1231  * \param  saoType SAO offset type
    1232  * \param  xPos x coordinate
    1233  * \param  yPos y coordinate
    1234  * \param  width block width
    1235  * \param  height block height
    1236  * \param  pbBorderAvail availabilities of block border pixels
    1237  */
    1238 Void TComSampleAdaptiveOffset::processSaoBlock(Pel* pDec, Pel* pRest, Int stride, Int saoType, UInt width, UInt height, Bool* pbBorderAvail, Int iYCbCr)
    1239 {
    1240   //variables
    1241   Int startX, startY, endX, endY, x, y;
    1242   Int signLeft,signRight,signDown,signDown1;
    1243   UInt edgeType;
    1244   Pel *pClipTbl = (iYCbCr==0)?m_pClipTable:m_pChromaClipTable;
    1245   Int *pOffsetBo = (iYCbCr==0)?m_iOffsetBo: m_iChromaOffsetBo;
    1246 
    1247   switch (saoType)
    1248   {
    1249   case SAO_EO_0: // dir: -
    1250     {
    1251 
    1252       startX = (pbBorderAvail[SGU_L]) ? 0 : 1;
    1253       endX   = (pbBorderAvail[SGU_R]) ? width : (width -1);
    1254       for (y=0; y< height; y++)
    1255       {
    1256         signLeft = xSign(pDec[startX] - pDec[startX-1]);
    1257         for (x=startX; x< endX; x++)
    1258         {
    1259           signRight =  xSign(pDec[x] - pDec[x+1]);
    1260           edgeType =  signRight + signLeft + 2;
    1261           signLeft  = -signRight;
    1262 
    1263           pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1264         }
    1265         pDec  += stride;
    1266         pRest += stride;
    1267       }
    1268       break;
    1269     }
    1270   case SAO_EO_1: // dir: |
    1271     {
    1272       startY = (pbBorderAvail[SGU_T]) ? 0 : 1;
    1273       endY   = (pbBorderAvail[SGU_B]) ? height : height-1;
    1274       if (!pbBorderAvail[SGU_T])
    1275       {
    1276         pDec  += stride;
    1277         pRest += stride;
    1278       }
    1279       for (x=0; x< width; x++)
    1280       {
    1281         m_iUpBuff1[x] = xSign(pDec[x] - pDec[x-stride]);
    1282       }
    1283       for (y=startY; y<endY; y++)
    1284       {
    1285         for (x=0; x< width; x++)
    1286         {
    1287           signDown  = xSign(pDec[x] - pDec[x+stride]);
    1288           edgeType = signDown + m_iUpBuff1[x] + 2;
    1289           m_iUpBuff1[x]= -signDown;
    1290 
    1291           pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1292         }
    1293         pDec  += stride;
    1294         pRest += stride;
    1295       }
    1296       break;
    1297     }
    1298   case SAO_EO_2: // dir: 135
    1299     {
    1300       Int posShift= stride + 1;
    1301 
    1302       startX = (pbBorderAvail[SGU_L]) ? 0 : 1 ;
    1303       endX   = (pbBorderAvail[SGU_R]) ? width : (width-1);
    1304 
    1305       //prepare 2nd line upper sign
    1306       pDec += stride;
    1307       for (x=startX; x< endX+1; x++)
    1308       {
    1309         m_iUpBuff1[x] = xSign(pDec[x] - pDec[x- posShift]);
    1310       }
    1311 
    1312       //1st line
    1313       pDec -= stride;
    1314       if(pbBorderAvail[SGU_TL])
    1315       {
    1316         x= 0;
    1317         edgeType      =  xSign(pDec[x] - pDec[x- posShift]) - m_iUpBuff1[x+1] + 2;
    1318         pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1319 
    1320       }
    1321       if(pbBorderAvail[SGU_T])
    1322       {
    1323         for(x= 1; x< endX; x++)
    1324         {
    1325           edgeType      =  xSign(pDec[x] - pDec[x- posShift]) - m_iUpBuff1[x+1] + 2;
    1326           pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1327         }
    1328       }
    1329       pDec   += stride;
    1330       pRest  += stride;
    1331 
    1332 
    1333       //middle lines
    1334       for (y= 1; y< height-1; y++)
    1335       {
    1336         for (x=startX; x<endX; x++)
    1337         {
    1338           signDown1      =  xSign(pDec[x] - pDec[x+ posShift]) ;
    1339           edgeType      =  signDown1 + m_iUpBuff1[x] + 2;
    1340           pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1341 
    1342           m_iUpBufft[x+1] = -signDown1;
    1343         }
    1344         m_iUpBufft[startX] = xSign(pDec[stride+startX] - pDec[startX-1]);
    1345 
    1346         ipSwap     = m_iUpBuff1;
    1347         m_iUpBuff1 = m_iUpBufft;
    1348         m_iUpBufft = ipSwap;
    1349 
    1350         pDec  += stride;
    1351         pRest += stride;
    1352       }
    1353 
    1354       //last line
    1355       if(pbBorderAvail[SGU_B])
    1356       {
    1357         for(x= startX; x< width-1; x++)
    1358         {
    1359           edgeType =  xSign(pDec[x] - pDec[x+ posShift]) + m_iUpBuff1[x] + 2;
    1360           pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1361         }
    1362       }
    1363       if(pbBorderAvail[SGU_BR])
    1364       {
    1365         x= width -1;
    1366         edgeType =  xSign(pDec[x] - pDec[x+ posShift]) + m_iUpBuff1[x] + 2;
    1367         pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1368       }
    1369       break;
    1370     }
    1371   case SAO_EO_3: // dir: 45
    1372     {
    1373       Int  posShift     = stride - 1;
    1374       startX = (pbBorderAvail[SGU_L]) ? 0 : 1;
    1375       endX   = (pbBorderAvail[SGU_R]) ? width : (width -1);
    1376 
    1377       //prepare 2nd line upper sign
    1378       pDec += stride;
    1379       for (x=startX-1; x< endX; x++)
    1380       {
    1381         m_iUpBuff1[x] = xSign(pDec[x] - pDec[x- posShift]);
    1382       }
    1383 
    1384 
    1385       //first line
    1386       pDec -= stride;
    1387       if(pbBorderAvail[SGU_T])
    1388       {
    1389         for(x= startX; x< width -1; x++)
    1390         {
    1391           edgeType = xSign(pDec[x] - pDec[x- posShift]) -m_iUpBuff1[x-1] + 2;
    1392           pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1393         }
    1394       }
    1395       if(pbBorderAvail[SGU_TR])
    1396       {
    1397         x= width-1;
    1398         edgeType = xSign(pDec[x] - pDec[x- posShift]) -m_iUpBuff1[x-1] + 2;
    1399         pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1400       }
    1401       pDec  += stride;
    1402       pRest += stride;
    1403 
    1404       //middle lines
    1405       for (y= 1; y< height-1; y++)
    1406       {
    1407         for(x= startX; x< endX; x++)
    1408         {
    1409           signDown1      =  xSign(pDec[x] - pDec[x+ posShift]) ;
    1410           edgeType      =  signDown1 + m_iUpBuff1[x] + 2;
    1411 
    1412           pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1413           m_iUpBuff1[x-1] = -signDown1;
    1414         }
    1415         m_iUpBuff1[endX-1] = xSign(pDec[endX-1 + stride] - pDec[endX]);
    1416 
    1417         pDec  += stride;
    1418         pRest += stride;
    1419       }
    1420 
    1421       //last line
    1422       if(pbBorderAvail[SGU_BL])
    1423       {
    1424         x= 0;
    1425         edgeType = xSign(pDec[x] - pDec[x+ posShift]) + m_iUpBuff1[x] + 2;
    1426         pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1427 
    1428       }
    1429       if(pbBorderAvail[SGU_B])
    1430       {
    1431         for(x= 1; x< endX; x++)
    1432         {
    1433           edgeType = xSign(pDec[x] - pDec[x+ posShift]) + m_iUpBuff1[x] + 2;
    1434           pRest[x] = pClipTbl[pDec[x] + m_iOffsetEo[edgeType]];
    1435         }
    1436       }
    1437       break;
    1438     }   
    1439   case SAO_BO:
    1440     {
    1441       for (y=0; y< height; y++)
    1442       {
    1443         for (x=0; x< width; x++)
    1444         {
    1445           pRest[x] = pOffsetBo[pDec[x]];
    1446         }
    1447         pRest += stride;
    1448         pDec  += stride;
    1449       }
    1450       break;
    1451     }
    1452   default: break;
    1453   }
    1454 
    1455 }
    1456 
    1457 /** sample adaptive offset process for one LCU crossing LCU boundary
    1458  * \param   iAddr, iSaoType, iYCbCr
    1459  */
    1460 Void TComSampleAdaptiveOffset::processSaoCuOrg(Int iAddr, Int iSaoType, Int iYCbCr)
    1461 {
    1462   Int x,y;
    1463   TComDataCU *pTmpCu = m_pcPic->getCU(iAddr);
    1464   Pel* pRec;
    1465   Int  iStride;
    1466   Int  iLcuWidth  = m_uiMaxCUWidth;
    1467   Int  iLcuHeight = m_uiMaxCUHeight;
    1468   UInt uiLPelX    = pTmpCu->getCUPelX();
    1469   UInt uiTPelY    = pTmpCu->getCUPelY();
    1470   UInt uiRPelX;
    1471   UInt uiBPelY;
    1472   Int  iSignLeft;
    1473   Int  iSignRight;
    1474   Int  iSignDown;
    1475   Int  iSignDown1;
    1476   Int  iSignDown2;
    1477   UInt uiEdgeType;
    1478   Int iPicWidthTmp;
    1479   Int iPicHeightTmp;
    1480   Int iStartX;
    1481   Int iStartY;
    1482   Int iEndX;
    1483   Int iEndY;
    1484   Int iIsChroma = (iYCbCr!=0)? 1:0;
    1485   Int iShift;
    1486   Int iCuHeightTmp;
    1487   Pel *pTmpLSwap;
    1488   Pel *pTmpL;
    1489   Pel *pTmpU;
    1490   Pel *pClipTbl = NULL;
    1491   Int *pOffsetBo = NULL;
    1492 
    1493   iPicWidthTmp  = m_iPicWidth  >> iIsChroma;
    1494   iPicHeightTmp = m_iPicHeight >> iIsChroma;
    1495   iLcuWidth     = iLcuWidth    >> iIsChroma;
    1496   iLcuHeight    = iLcuHeight   >> iIsChroma;
    1497   uiLPelX       = uiLPelX      >> iIsChroma;
    1498   uiTPelY       = uiTPelY      >> iIsChroma;
    1499   uiRPelX       = uiLPelX + iLcuWidth  ;
    1500   uiBPelY       = uiTPelY + iLcuHeight ;
    1501   uiRPelX       = uiRPelX > iPicWidthTmp  ? iPicWidthTmp  : uiRPelX;
    1502   uiBPelY       = uiBPelY > iPicHeightTmp ? iPicHeightTmp : uiBPelY;
    1503   iLcuWidth     = uiRPelX - uiLPelX;
    1504   iLcuHeight    = uiBPelY - uiTPelY;
    1505 
    1506   if(pTmpCu->getPic()==0)
    1507   {
    1508     return;
    1509   }
    1510   if (iYCbCr == 0)
    1511   {
    1512     pRec       = m_pcPic->getPicYuvRec()->getLumaAddr(iAddr);
    1513     iStride    = m_pcPic->getStride();
    1514   }
    1515   else if (iYCbCr == 1)
    1516   {
    1517     pRec       = m_pcPic->getPicYuvRec()->getCbAddr(iAddr);
    1518     iStride    = m_pcPic->getCStride();
    1519   }
    1520   else
    1521   {
    1522     pRec       = m_pcPic->getPicYuvRec()->getCrAddr(iAddr);
    1523     iStride    = m_pcPic->getCStride();
    1524   }
    1525 
    1526 //   if (iSaoType!=SAO_BO_0 || iSaoType!=SAO_BO_1)
    1527   {
    1528     iCuHeightTmp = (m_uiMaxCUHeight >> iIsChroma);
    1529     iShift = (m_uiMaxCUWidth>> iIsChroma)-1;
    1530     for (Int i=0;i<iCuHeightTmp+1;i++)
    1531     {
    1532       m_pTmpL2[i] = pRec[iShift];
    1533       pRec += iStride;
    1534     }
    1535     pRec -= (iStride*(iCuHeightTmp+1));
    1536 
    1537     pTmpL = m_pTmpL1;
    1538     pTmpU = &(m_pTmpU1[uiLPelX]);
    1539   }
    1540 
    1541   pClipTbl = (iYCbCr==0)? m_pClipTable:m_pChromaClipTable;
    1542   pOffsetBo = (iYCbCr==0)? m_iOffsetBo:m_iChromaOffsetBo;
    1543 
    1544   switch (iSaoType)
    1545   {
    1546   case SAO_EO_0: // dir: -
    1547     {
    1548       iStartX = (uiLPelX == 0) ? 1 : 0;
    1549       iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth;
    1550       for (y=0; y<iLcuHeight; y++)
    1551       {
    1552         iSignLeft = xSign(pRec[iStartX] - pTmpL[y]);
    1553         for (x=iStartX; x< iEndX; x++)
    1554         {
    1555           iSignRight =  xSign(pRec[x] - pRec[x+1]);
    1556           uiEdgeType =  iSignRight + iSignLeft + 2;
    1557           iSignLeft  = -iSignRight;
    1558 
    1559           pRec[x] = pClipTbl[pRec[x] + m_iOffsetEo[uiEdgeType]];
    1560         }
    1561         pRec += iStride;
    1562       }
    1563       break;
    1564     }
    1565   case SAO_EO_1: // dir: |
    1566     {
    1567       iStartY = (uiTPelY == 0) ? 1 : 0;
    1568       iEndY   = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight;
    1569       if (uiTPelY == 0)
    1570       {
    1571         pRec += iStride;
    1572       }
    1573       for (x=0; x< iLcuWidth; x++)
    1574       {
    1575         m_iUpBuff1[x] = xSign(pRec[x] - pTmpU[x]);
    1576       }
    1577       for (y=iStartY; y<iEndY; y++)
    1578       {
    1579         for (x=0; x<iLcuWidth; x++)
    1580         {
    1581           iSignDown  = xSign(pRec[x] - pRec[x+iStride]);
    1582           uiEdgeType = iSignDown + m_iUpBuff1[x] + 2;
    1583           m_iUpBuff1[x]= -iSignDown;
    1584 
    1585           pRec[x] = pClipTbl[pRec[x] + m_iOffsetEo[uiEdgeType]];
    1586         }
    1587         pRec += iStride;
    1588       }
    1589       break;
    1590     }
    1591   case SAO_EO_2: // dir: 135
    1592     {
    1593       iStartX = (uiLPelX == 0)            ? 1 : 0;
    1594       iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth;
    1595 
    1596       iStartY = (uiTPelY == 0) ?             1 : 0;
    1597       iEndY   = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight;
    1598 
    1599       if (uiTPelY == 0)
    1600       {
    1601         pRec += iStride;
    1602       }
    1603 
    1604       for (x=iStartX; x<iEndX; x++)
    1605       {
    1606         m_iUpBuff1[x] = xSign(pRec[x] - pTmpU[x-1]);
    1607       }
    1608       for (y=iStartY; y<iEndY; y++)
    1609       {
    1610         iSignDown2 = xSign(pRec[iStride+iStartX] - pTmpL[y]);
    1611         for (x=iStartX; x<iEndX; x++)
    1612         {
    1613           iSignDown1      =  xSign(pRec[x] - pRec[x+iStride+1]) ;
    1614           uiEdgeType      =  iSignDown1 + m_iUpBuff1[x] + 2;
    1615           m_iUpBufft[x+1] = -iSignDown1;
    1616           pRec[x] = pClipTbl[pRec[x] + m_iOffsetEo[uiEdgeType]];
    1617         }
    1618         m_iUpBufft[iStartX] = iSignDown2;
    1619 
    1620         ipSwap     = m_iUpBuff1;
    1621         m_iUpBuff1 = m_iUpBufft;
    1622         m_iUpBufft = ipSwap;
    1623 
    1624         pRec += iStride;
    1625       }
    1626       break;
    1627     }
    1628   case SAO_EO_3: // dir: 45
    1629     {
    1630       iStartX = (uiLPelX == 0) ? 1 : 0;
    1631       iEndX   = (uiRPelX == iPicWidthTmp) ? iLcuWidth-1 : iLcuWidth;
    1632 
    1633       iStartY = (uiTPelY == 0) ? 1 : 0;
    1634       iEndY   = (uiBPelY == iPicHeightTmp) ? iLcuHeight-1 : iLcuHeight;
    1635 
    1636       if (iStartY == 1)
    1637       {
    1638         pRec += iStride;
    1639       }
    1640 
    1641       for (x=iStartX-1; x<iEndX; x++)
    1642       {
    1643         m_iUpBuff1[x] = xSign(pRec[x] - pTmpU[x+1]);
    1644       }
    1645       for (y=iStartY; y<iEndY; y++)
    1646       {
    1647         x=iStartX;
    1648         iSignDown1      =  xSign(pRec[x] - pTmpL[y+1]) ;
    1649         uiEdgeType      =  iSignDown1 + m_iUpBuff1[x] + 2;
    1650         m_iUpBuff1[x-1] = -iSignDown1;
    1651         pRec[x] = pClipTbl[pRec[x] + m_iOffsetEo[uiEdgeType]];
    1652         for (x=iStartX+1; x<iEndX; x++)
    1653         {
    1654           iSignDown1      =  xSign(pRec[x] - pRec[x+iStride-1]) ;
    1655           uiEdgeType      =  iSignDown1 + m_iUpBuff1[x] + 2;
    1656           m_iUpBuff1[x-1] = -iSignDown1;
    1657           pRec[x] = pClipTbl[pRec[x] + m_iOffsetEo[uiEdgeType]];
    1658         }
    1659         m_iUpBuff1[iEndX-1] = xSign(pRec[iEndX-1 + iStride] - pRec[iEndX]);
    1660 
    1661         pRec += iStride;
    1662       }
    1663       break;
    1664     }   
    1665   case SAO_BO:
    1666     {
    1667       for (y=0; y<iLcuHeight; y++)
    1668       {
    1669         for (x=0; x<iLcuWidth; x++)
    1670         {
    1671           pRec[x] = pOffsetBo[pRec[x]];
    1672         }
    1673         pRec += iStride;
    1674       }
    1675       break;
    1676     }
    1677   default: break;
    1678   }
    1679 //   if (iSaoType!=SAO_BO_0 || iSaoType!=SAO_BO_1)
    1680   {
    1681     pTmpLSwap = m_pTmpL1;
    1682     m_pTmpL1  = m_pTmpL2;
    1683     m_pTmpL2  = pTmpLSwap;
    1684   }
    1685 }
    1686 /** Sample adaptive offset process
    1687  * \param pcPic, pcSaoParam 
    1688  */
    1689 Void TComSampleAdaptiveOffset::SAOProcess(SAOParam* pcSaoParam)
    1690 {
    1691   {
    1692     m_uiSaoBitIncreaseY = max(g_bitDepthY - 10, 0);
    1693     m_uiSaoBitIncreaseC = max(g_bitDepthC - 10, 0);
    1694 
    1695     if(m_bUseNIF)
    1696     {
    1697       m_pcPic->getPicYuvRec()->copyToPic(m_pcYuvTmp);
    1698     }
    1699     if (m_saoLcuBasedOptimization)
    1700     {
    1701       pcSaoParam->oneUnitFlag[0] = 0; 
    1702       pcSaoParam->oneUnitFlag[1] = 0; 
    1703       pcSaoParam->oneUnitFlag[2] = 0; 
    1704     }
    1705     Int iY  = 0;
    1706     {
    1707       processSaoUnitAll( pcSaoParam->saoLcuParam[iY], pcSaoParam->oneUnitFlag[iY], iY);
    1708     }
    1709     {
    1710        processSaoUnitAll( pcSaoParam->saoLcuParam[1], pcSaoParam->oneUnitFlag[1], 1);//Cb
    1711        processSaoUnitAll( pcSaoParam->saoLcuParam[2], pcSaoParam->oneUnitFlag[2], 2);//Cr
    1712     }
    1713     m_pcPic = NULL;
    1714   }
    1715 }
    1716 
    1717 Pel* TComSampleAdaptiveOffset::getPicYuvAddr(TComPicYuv* pcPicYuv, Int iYCbCr, Int iAddr)
    1718 {
    1719   switch (iYCbCr)
    1720   {
    1721   case 0:
    1722     return pcPicYuv->getLumaAddr(iAddr);
    1723     break;
    1724   case 1:
    1725     return pcPicYuv->getCbAddr(iAddr);
    1726     break;
    1727   case 2:
    1728     return pcPicYuv->getCrAddr(iAddr);
    1729     break;
    1730   default:
    1731     return NULL;
    1732     break;
    1733   }
    1734 }
    1735 /** Process SAO all units
    1736  * \param saoLcuParam SAO LCU parameters
    1737  * \param oneUnitFlag one unit flag
    1738  * \param yCbCr color componet index
    1739  */
    1740 Void TComSampleAdaptiveOffset::processSaoUnitAll(SaoLcuParam* saoLcuParam, Bool oneUnitFlag, Int yCbCr)
    1741 {
    1742   Pel *pRec;
    1743   Int picWidthTmp;
    1744 
    1745   if (yCbCr == 0)
    1746   {
    1747     pRec        = m_pcPic->getPicYuvRec()->getLumaAddr();
    1748     picWidthTmp = m_iPicWidth;
    1749   }
    1750   else if (yCbCr == 1)
    1751   {
    1752     pRec        = m_pcPic->getPicYuvRec()->getCbAddr();
    1753     picWidthTmp = m_iPicWidth>>1;
    1754   }
    1755   else
    1756   {
    1757     pRec        = m_pcPic->getPicYuvRec()->getCrAddr();
    1758     picWidthTmp = m_iPicWidth>>1;
    1759   }
    1760 
    1761   memcpy(m_pTmpU1, pRec, sizeof(Pel)*picWidthTmp);
    1762 
    1763   Int  i;
    1764   UInt edgeType;
    1765   Pel* ppLumaTable = NULL;
    1766   Pel* pClipTable = NULL;
    1767   Int* pOffsetBo = NULL;
    1768   Int  typeIdx;
    1769 
    1770   Int offset[LUMA_GROUP_NUM+1];
    1771   Int idxX;
    1772   Int idxY;
    1773   Int addr;
    1774   Int frameWidthInCU = m_pcPic->getFrameWidthInCU();
    1775   Int frameHeightInCU = m_pcPic->getFrameHeightInCU();
    1776   Int stride;
    1777   Pel *tmpUSwap;
    1778   Int isChroma = (yCbCr == 0) ? 0:1;
    1779   Bool mergeLeftFlag;
    1780   Int saoBitIncrease = (yCbCr == 0) ? m_uiSaoBitIncreaseY : m_uiSaoBitIncreaseC;
    1781 
    1782   pOffsetBo = (yCbCr==0) ? m_iOffsetBo : m_iChromaOffsetBo;
    1783 
    1784   offset[0] = 0;
    1785   for (idxY = 0; idxY< frameHeightInCU; idxY++)
    1786   {
    1787     addr = idxY * frameWidthInCU;
    1788     if (yCbCr == 0)
    1789     {
    1790       pRec  = m_pcPic->getPicYuvRec()->getLumaAddr(addr);
    1791       stride = m_pcPic->getStride();
    1792       picWidthTmp = m_iPicWidth;
    1793     }
    1794     else if (yCbCr == 1)
    1795     {
    1796       pRec  = m_pcPic->getPicYuvRec()->getCbAddr(addr);
    1797       stride = m_pcPic->getCStride();
    1798       picWidthTmp = m_iPicWidth>>1;
    1799     }
    1800     else
    1801     {
    1802       pRec  = m_pcPic->getPicYuvRec()->getCrAddr(addr);
    1803       stride = m_pcPic->getCStride();
    1804       picWidthTmp = m_iPicWidth>>1;
    1805     }
    1806 
    1807     //     pRec += iStride*(m_uiMaxCUHeight-1);
    1808     for (i=0;i<(m_uiMaxCUHeight>>isChroma)+1;i++)
    1809     {
    1810       m_pTmpL1[i] = pRec[0];
    1811       pRec+=stride;
    1812     }
    1813     pRec-=(stride<<1);
    1814 
    1815     memcpy(m_pTmpU2, pRec, sizeof(Pel)*picWidthTmp);
    1816 
    1817     for (idxX = 0; idxX < frameWidthInCU; idxX++)
    1818     {
    1819       addr = idxY * frameWidthInCU + idxX;
    1820 
    1821       if (oneUnitFlag)
    1822       {
    1823         typeIdx = saoLcuParam[0].typeIdx;
    1824         mergeLeftFlag = (addr == 0)? 0:1;
    1825       }
    1826       else
    1827       {
    1828         typeIdx = saoLcuParam[addr].typeIdx;
    1829         mergeLeftFlag = saoLcuParam[addr].mergeLeftFlag;
    1830       }
    1831       if (typeIdx>=0)
    1832       {
    1833         if (!mergeLeftFlag)
    1834         {
    1835 
    1836           if (typeIdx == SAO_BO)
    1837           {
    1838             for (i=0; i<SAO_MAX_BO_CLASSES+1;i++)
    1839             {
    1840               offset[i] = 0;
    1841             }
    1842             for (i=0; i<saoLcuParam[addr].length; i++)
    1843             {
    1844               offset[ (saoLcuParam[addr].subTypeIdx +i)%SAO_MAX_BO_CLASSES  +1] = saoLcuParam[addr].offset[i] << saoBitIncrease;
    1845             }
    1846 
    1847             ppLumaTable = (yCbCr==0)?m_lumaTableBo:m_chromaTableBo;
    1848             pClipTable = (yCbCr==0)?m_pClipTable:m_pChromaClipTable;
    1849 
    1850             Int bitDepth = (yCbCr==0) ? g_bitDepthY : g_bitDepthC;
    1851             for (i=0;i<(1<<bitDepth);i++)
    1852             {
    1853               pOffsetBo[i] = pClipTable[i + offset[ppLumaTable[i]]];
    1854             }
    1855 
    1856           }
    1857           if (typeIdx == SAO_EO_0 || typeIdx == SAO_EO_1 || typeIdx == SAO_EO_2 || typeIdx == SAO_EO_3)
    1858           {
    1859             for (i=0;i<saoLcuParam[addr].length;i++)
    1860             {
    1861               offset[i+1] = saoLcuParam[addr].offset[i] << saoBitIncrease;
    1862             }
    1863             for (edgeType=0;edgeType<6;edgeType++)
    1864             {
    1865               m_iOffsetEo[edgeType]= offset[m_auiEoTable[edgeType]];
    1866             }
    1867           }
    1868         }
    1869         processSaoCu(addr, typeIdx, yCbCr);
    1870       }
    1871       else
    1872       {
    1873         if (idxX != (frameWidthInCU-1))
    1874         {
    1875           if (yCbCr == 0)
    1876           {
    1877             pRec  = m_pcPic->getPicYuvRec()->getLumaAddr(addr);
    1878             stride = m_pcPic->getStride();
    1879           }
    1880           else if (yCbCr == 1)
    1881           {
    1882             pRec  = m_pcPic->getPicYuvRec()->getCbAddr(addr);
    1883             stride = m_pcPic->getCStride();
    1884           }
    1885           else
    1886           {
    1887             pRec  = m_pcPic->getPicYuvRec()->getCrAddr(addr);
    1888             stride = m_pcPic->getCStride();
    1889           }
    1890           Int widthShift = m_uiMaxCUWidth>>isChroma;
    1891           for (i=0;i<(m_uiMaxCUHeight>>isChroma)+1;i++)
    1892           {
    1893             m_pTmpL1[i] = pRec[widthShift-1];
    1894             pRec+=stride;
    1895           }
    1896         }
    1897       }
    1898     }
    1899     tmpUSwap = m_pTmpU1;
    1900     m_pTmpU1 = m_pTmpU2;
    1901     m_pTmpU2 = tmpUSwap;
    1902   }
    1903 
    1904 }
    1905 /** Reset SAO LCU part
    1906  * \param saoLcuParam
    1907  */
    1908 Void TComSampleAdaptiveOffset::resetLcuPart(SaoLcuParam* saoLcuParam)
    1909 {
    1910   Int i,j;
    1911   for (i=0;i<m_iNumCuInWidth*m_iNumCuInHeight;i++)
    1912   {
    1913     saoLcuParam[i].mergeUpFlag     =  1;
    1914     saoLcuParam[i].mergeLeftFlag =  0;
    1915     saoLcuParam[i].partIdx   =  0;
    1916     saoLcuParam[i].typeIdx      = -1;
    1917     for (j=0;j<MAX_NUM_SAO_OFFSETS;j++)
    1918     {
    1919       saoLcuParam[i].offset[j] = 0;
    1920     }
    1921     saoLcuParam[i].subTypeIdx = 0;
    1922   }
    1923 }
    1924 
    1925 /** convert QP part to SAO unit
    1926 * \param saoParam SAO parameter
    1927 * \param partIdx SAO part index
    1928 * \param yCbCr color component index
    1929  */
    1930 Void TComSampleAdaptiveOffset::convertQT2SaoUnit(SAOParam *saoParam, UInt partIdx, Int yCbCr)
    1931 {
    1932 
    1933   SAOQTPart*  saoPart= &(saoParam->psSaoPart[yCbCr][partIdx]);
    1934   if (!saoPart->bSplit)
    1935   {
    1936     convertOnePart2SaoUnit(saoParam, partIdx, yCbCr);
    1937     return;
    1938   }
    1939 
    1940   if (saoPart->PartLevel < m_uiMaxSplitLevel)
    1941   {
    1942     convertQT2SaoUnit(saoParam, saoPart->DownPartsIdx[0], yCbCr);
    1943     convertQT2SaoUnit(saoParam, saoPart->DownPartsIdx[1], yCbCr);
    1944     convertQT2SaoUnit(saoParam, saoPart->DownPartsIdx[2], yCbCr);
    1945     convertQT2SaoUnit(saoParam, saoPart->DownPartsIdx[3], yCbCr);
    1946   }
    1947 }
    1948 /** convert one SAO part to SAO unit
    1949 * \param saoParam SAO parameter
    1950 * \param partIdx SAO part index
    1951 * \param yCbCr color component index
    1952  */
    1953 Void TComSampleAdaptiveOffset::convertOnePart2SaoUnit(SAOParam *saoParam, UInt partIdx, Int yCbCr)
    1954 {
    1955   Int j;
    1956   Int idxX;
    1957   Int idxY;
    1958   Int addr;
    1959   Int frameWidthInCU = m_pcPic->getFrameWidthInCU();
    1960   SAOQTPart* saoQTPart = saoParam->psSaoPart[yCbCr];
    1961   SaoLcuParam* saoLcuParam = saoParam->saoLcuParam[yCbCr];
    1962 
    1963   for (idxY = saoQTPart[partIdx].StartCUY; idxY<= saoQTPart[partIdx].EndCUY; idxY++)
    1964   {
    1965     for (idxX = saoQTPart[partIdx].StartCUX; idxX<= saoQTPart[partIdx].EndCUX; idxX++)
    1966     {
    1967       addr = idxY * frameWidthInCU + idxX;
    1968       saoLcuParam[addr].partIdxTmp = (Int)partIdx;
    1969       saoLcuParam[addr].typeIdx    = saoQTPart[partIdx].iBestType;
    1970       saoLcuParam[addr].subTypeIdx = saoQTPart[partIdx].subTypeIdx;
    1971       if (saoLcuParam[addr].typeIdx!=-1)
    1972       {
    1973         saoLcuParam[addr].length    = saoQTPart[partIdx].iLength;
    1974         for (j=0;j<MAX_NUM_SAO_OFFSETS;j++)
    1975         {
    1976           saoLcuParam[addr].offset[j] = saoQTPart[partIdx].iOffset[j];
    1977         }
    1978       }
    1979       else
    1980       {
    1981         saoLcuParam[addr].length    = 0;
    1982         saoLcuParam[addr].subTypeIdx = saoQTPart[partIdx].subTypeIdx;
    1983         for (j=0;j<MAX_NUM_SAO_OFFSETS;j++)
    1984         {
    1985           saoLcuParam[addr].offset[j] = 0;
    1986         }
    1987       }
    1988     }
    1989   }
    1990 }
    1991 
    1992 Void TComSampleAdaptiveOffset::resetSaoUnit(SaoLcuParam* saoUnit)
    1993 {
    1994   saoUnit->partIdx       = 0;
    1995   saoUnit->partIdxTmp    = 0;
    1996   saoUnit->mergeLeftFlag = 0;
    1997   saoUnit->mergeUpFlag   = 0;
    1998   saoUnit->typeIdx       = -1;
    1999   saoUnit->length        = 0;
    2000   saoUnit->subTypeIdx    = 0;
    2001 
    2002   for (Int i=0;i<4;i++)
    2003   {
    2004     saoUnit->offset[i] = 0;
    2005   }
    2006 }
    2007 
    2008 Void TComSampleAdaptiveOffset::copySaoUnit(SaoLcuParam* saoUnitDst, SaoLcuParam* saoUnitSrc )
    2009 {
    2010   saoUnitDst->mergeLeftFlag = saoUnitSrc->mergeLeftFlag;
    2011   saoUnitDst->mergeUpFlag   = saoUnitSrc->mergeUpFlag;
    2012   saoUnitDst->typeIdx       = saoUnitSrc->typeIdx;
    2013   saoUnitDst->length        = saoUnitSrc->length;
    2014 
    2015   saoUnitDst->subTypeIdx  = saoUnitSrc->subTypeIdx;
    2016   for (Int i=0;i<4;i++)
    2017   {
    2018     saoUnitDst->offset[i] = saoUnitSrc->offset[i];
    2019   }
    2020 }
    2021 #endif
     699
    2022700/** PCM LF disable process.
    2023701 * \param pcPic picture (TComPic) pointer
Note: See TracChangeset for help on using the changeset viewer.