Ignore:
Timestamp:
13 Aug 2015, 17:38:13 (9 years ago)
Author:
tech
Message:

Merged 14.1-update-dev1@1312.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp

    r1179 r1313  
    22 * License, included below. This software may be subject to other third party
    33 * and contributor rights, including patent rights, and no such rights are
    4  * granted under this license. 
     4 * granted under this license.
    55 *
    66 * Copyright (c) 2010-2015, ITU/ISO/IEC
     
    3232 */
    3333
    34 /** 
     34/**
    3535 \file     TEncSampleAdaptiveOffset.cpp
    3636 \brief       estimation part of sample adaptive offset class
     
    4646
    4747
    48 /** rounding with IBDI
    49  * \param  x
    50  */
     48//! rounding with IBDI
    5149inline Double xRoundIbdi2(Int bitDepth, Double x)
    5250{
     
    6260TEncSampleAdaptiveOffset::TEncSampleAdaptiveOffset()
    6361{
    64   m_pppcRDSbacCoder = NULL;           
     62  m_pppcRDSbacCoder = NULL;
    6563  m_pcRDGoOnSbacCoder = NULL;
    66   m_pppcBinCoderCABAC = NULL;   
     64  m_pppcBinCoderCABAC = NULL;
    6765  m_statData = NULL;
    68 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    6966  m_preDBFstatData = NULL;
    70 #endif
    7167}
    7268
     
    7672}
    7773
    78 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    7974Void TEncSampleAdaptiveOffset::createEncData(Bool isPreDBFSamplesUsed)
    80 #else
    81 Void TEncSampleAdaptiveOffset::createEncData()
    82 #endif
    8375{
    8476
    8577  //cabac coder for RDO
    8678  m_pppcRDSbacCoder = new TEncSbac* [NUM_SAO_CABACSTATE_LABELS];
     79#if FAST_BIT_EST
    8780  m_pppcBinCoderCABAC = new TEncBinCABACCounter* [NUM_SAO_CABACSTATE_LABELS];
     81#else
     82  m_pppcBinCoderCABAC = new TEncBinCABAC* [NUM_SAO_CABACSTATE_LABELS];
     83#endif
    8884
    8985  for(Int cs=0; cs < NUM_SAO_CABACSTATE_LABELS; cs++)
    9086  {
    9187    m_pppcRDSbacCoder[cs] = new TEncSbac;
     88#if FAST_BIT_EST
    9289    m_pppcBinCoderCABAC[cs] = new TEncBinCABACCounter;
     90#else
     91    m_pppcBinCoderCABAC[cs] = new TEncBinCABAC;
     92#endif
    9393    m_pppcRDSbacCoder   [cs]->init( m_pppcBinCoderCABAC [cs] );
    9494  }
     
    9999  for(Int i=0; i< m_numCTUsPic; i++)
    100100  {
    101     m_statData[i] = new SAOStatData*[NUM_SAO_COMPONENTS];
    102     for(Int compIdx=0; compIdx < NUM_SAO_COMPONENTS; compIdx++)
     101    m_statData[i] = new SAOStatData*[MAX_NUM_COMPONENT];
     102    for(Int compIdx=0; compIdx < MAX_NUM_COMPONENT; compIdx++)
    103103    {
    104104      m_statData[i][compIdx] = new SAOStatData[NUM_SAO_NEW_TYPES];
    105105    }
    106106  }
    107 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    108107  if(isPreDBFSamplesUsed)
    109108  {
     
    111110    for(Int i=0; i< m_numCTUsPic; i++)
    112111    {
    113       m_preDBFstatData[i] = new SAOStatData*[NUM_SAO_COMPONENTS];
    114       for(Int compIdx=0; compIdx < NUM_SAO_COMPONENTS; compIdx++)
     112      m_preDBFstatData[i] = new SAOStatData*[MAX_NUM_COMPONENT];
     113      for(Int compIdx=0; compIdx < MAX_NUM_COMPONENT; compIdx++)
    115114      {
    116115        m_preDBFstatData[i][compIdx] = new SAOStatData[NUM_SAO_NEW_TYPES];
     
    119118
    120119  }
    121 #endif
    122 
    123 #if SAO_ENCODING_CHOICE
     120
    124121  ::memset(m_saoDisabledRate, 0, sizeof(m_saoDisabledRate));
    125 #endif
    126122
    127123  for(Int typeIdc=0; typeIdc < NUM_SAO_NEW_TYPES; typeIdc++)
    128124  {
    129     m_skipLinesR[SAO_Y ][typeIdc]= 5;
    130     m_skipLinesR[SAO_Cb][typeIdc]= m_skipLinesR[SAO_Cr][typeIdc]= 3;
    131 
    132     m_skipLinesB[SAO_Y ][typeIdc]= 4;
    133     m_skipLinesB[SAO_Cb][typeIdc]= m_skipLinesB[SAO_Cr][typeIdc]= 2;
    134 
    135 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
     125    m_skipLinesR[COMPONENT_Y ][typeIdc]= 5;
     126    m_skipLinesR[COMPONENT_Cb][typeIdc]= m_skipLinesR[COMPONENT_Cr][typeIdc]= 3;
     127
     128    m_skipLinesB[COMPONENT_Y ][typeIdc]= 4;
     129    m_skipLinesB[COMPONENT_Cb][typeIdc]= m_skipLinesB[COMPONENT_Cr][typeIdc]= 2;
     130
    136131    if(isPreDBFSamplesUsed)
    137132    {
     
    140135      case SAO_TYPE_EO_0:
    141136        {
    142           m_skipLinesR[SAO_Y ][typeIdc]= 5;
    143           m_skipLinesR[SAO_Cb][typeIdc]= m_skipLinesR[SAO_Cr][typeIdc]= 3;
    144 
    145           m_skipLinesB[SAO_Y ][typeIdc]= 3;
    146           m_skipLinesB[SAO_Cb][typeIdc]= m_skipLinesB[SAO_Cr][typeIdc]= 1;
     137          m_skipLinesR[COMPONENT_Y ][typeIdc]= 5;
     138          m_skipLinesR[COMPONENT_Cb][typeIdc]= m_skipLinesR[COMPONENT_Cr][typeIdc]= 3;
     139
     140          m_skipLinesB[COMPONENT_Y ][typeIdc]= 3;
     141          m_skipLinesB[COMPONENT_Cb][typeIdc]= m_skipLinesB[COMPONENT_Cr][typeIdc]= 1;
    147142        }
    148143        break;
    149144      case SAO_TYPE_EO_90:
    150145        {
    151           m_skipLinesR[SAO_Y ][typeIdc]= 4;
    152           m_skipLinesR[SAO_Cb][typeIdc]= m_skipLinesR[SAO_Cr][typeIdc]= 2;
    153 
    154           m_skipLinesB[SAO_Y ][typeIdc]= 4;
    155           m_skipLinesB[SAO_Cb][typeIdc]= m_skipLinesB[SAO_Cr][typeIdc]= 2;
     146          m_skipLinesR[COMPONENT_Y ][typeIdc]= 4;
     147          m_skipLinesR[COMPONENT_Cb][typeIdc]= m_skipLinesR[COMPONENT_Cr][typeIdc]= 2;
     148
     149          m_skipLinesB[COMPONENT_Y ][typeIdc]= 4;
     150          m_skipLinesB[COMPONENT_Cb][typeIdc]= m_skipLinesB[COMPONENT_Cr][typeIdc]= 2;
    156151        }
    157152        break;
     
    159154      case SAO_TYPE_EO_45:
    160155        {
    161           m_skipLinesR[SAO_Y ][typeIdc]= 5;
    162           m_skipLinesR[SAO_Cb][typeIdc]= m_skipLinesR[SAO_Cr][typeIdc]= 3;
    163 
    164           m_skipLinesB[SAO_Y ][typeIdc]= 4;
    165           m_skipLinesB[SAO_Cb][typeIdc]= m_skipLinesB[SAO_Cr][typeIdc]= 2;
     156          m_skipLinesR[COMPONENT_Y ][typeIdc]= 5;
     157          m_skipLinesR[COMPONENT_Cb][typeIdc]= m_skipLinesR[COMPONENT_Cr][typeIdc]= 3;
     158
     159          m_skipLinesB[COMPONENT_Y ][typeIdc]= 4;
     160          m_skipLinesB[COMPONENT_Cb][typeIdc]= m_skipLinesB[COMPONENT_Cr][typeIdc]= 2;
    166161        }
    167162        break;
    168163      case SAO_TYPE_BO:
    169164        {
    170           m_skipLinesR[SAO_Y ][typeIdc]= 4;
    171           m_skipLinesR[SAO_Cb][typeIdc]= m_skipLinesR[SAO_Cr][typeIdc]= 2;
    172 
    173           m_skipLinesB[SAO_Y ][typeIdc]= 3;
    174           m_skipLinesB[SAO_Cb][typeIdc]= m_skipLinesB[SAO_Cr][typeIdc]= 1;
     165          m_skipLinesR[COMPONENT_Y ][typeIdc]= 4;
     166          m_skipLinesR[COMPONENT_Cb][typeIdc]= m_skipLinesR[COMPONENT_Cr][typeIdc]= 2;
     167
     168          m_skipLinesB[COMPONENT_Y ][typeIdc]= 3;
     169          m_skipLinesB[COMPONENT_Cb][typeIdc]= m_skipLinesB[COMPONENT_Cr][typeIdc]= 1;
    175170        }
    176171        break;
     
    183178      }
    184179    }
    185 #endif   
    186180  }
    187181
     
    212206    for(Int i=0; i< m_numCTUsPic; i++)
    213207    {
    214       for(Int compIdx=0; compIdx< NUM_SAO_COMPONENTS; compIdx++)
     208      for(Int compIdx=0; compIdx< MAX_NUM_COMPONENT; compIdx++)
    215209      {
    216210        delete[] m_statData[i][compIdx];
     
    220214    delete[] m_statData; m_statData = NULL;
    221215  }
    222 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    223216  if(m_preDBFstatData != NULL)
    224217  {
    225218    for(Int i=0; i< m_numCTUsPic; i++)
    226219    {
    227       for(Int compIdx=0; compIdx< NUM_SAO_COMPONENTS; compIdx++)
     220      for(Int compIdx=0; compIdx< MAX_NUM_COMPONENT; compIdx++)
    228221      {
    229222        delete[] m_preDBFstatData[i][compIdx];
     
    233226    delete[] m_preDBFstatData; m_preDBFstatData = NULL;
    234227  }
    235 
    236 #endif
    237 }
    238 
    239 Void TEncSampleAdaptiveOffset::initRDOCabacCoder(TEncSbac* pcRDGoOnSbacCoder, TComSlice* pcSlice)
     228}
     229
     230Void TEncSampleAdaptiveOffset::initRDOCabacCoder(TEncSbac* pcRDGoOnSbacCoder, TComSlice* pcSlice)
    240231{
    241232  m_pcRDGoOnSbacCoder = pcRDGoOnSbacCoder;
    242   m_pcRDGoOnSbacCoder->setSlice(pcSlice);
    243   m_pcRDGoOnSbacCoder->resetEntropy();
     233  m_pcRDGoOnSbacCoder->resetEntropy(pcSlice);
    244234  m_pcRDGoOnSbacCoder->resetBits();
    245235
     
    249239
    250240
    251 Void TEncSampleAdaptiveOffset::SAOProcess(TComPic* pPic, Bool* sliceEnabled, const Double *lambdas
    252 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    253                                          , Bool isPreDBFSamplesUsed
    254 #endif
    255                                           )
     241Void TEncSampleAdaptiveOffset::SAOProcess(TComPic* pPic, Bool* sliceEnabled, const Double *lambdas, const Bool bTestSAODisableAtPictureLevel, const Double saoEncodingRate, const Double saoEncodingRateChroma, Bool isPreDBFSamplesUsed )
    256242{
    257243  TComPicYuv* orgYuv= pPic->getPicYuvOrg();
    258244  TComPicYuv* resYuv= pPic->getPicYuvRec();
    259   m_lambda[SAO_Y]= lambdas[0]; m_lambda[SAO_Cb]= lambdas[1]; m_lambda[SAO_Cr]= lambdas[2];
     245  memcpy(m_lambda, lambdas, sizeof(m_lambda));
    260246  TComPicYuv* srcYuv = m_tempPicYuv;
    261247  resYuv->copyToPic(srcYuv);
     
    265251  //collect statistics
    266252  getStatistics(m_statData, orgYuv, srcYuv, pPic);
    267 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    268253  if(isPreDBFSamplesUsed)
    269254  {
    270255    addPreDBFStatistics(m_statData);
    271256  }
    272 #endif
    273   //slice on/off
    274   decidePicParams(sliceEnabled, pPic->getSlice(0)->getDepth());
    275 
    276   //block on/off
     257  //slice on/off
     258  decidePicParams(sliceEnabled, pPic->getSlice(0)->getDepth(), saoEncodingRate, saoEncodingRateChroma);
     259
     260  //block on/off
    277261  SAOBlkParam* reconParams = new SAOBlkParam[m_numCTUsPic]; //temporary parameter buffer for storing reconstructed SAO parameters
    278   decideBlkParams(pPic, sliceEnabled, m_statData, srcYuv, resYuv, reconParams, pPic->getPicSym()->getSAOBlkParam());
     262  decideBlkParams(pPic, sliceEnabled, m_statData, srcYuv, resYuv, reconParams, pPic->getPicSym()->getSAOBlkParam(), bTestSAODisableAtPictureLevel, saoEncodingRate, saoEncodingRateChroma);
    279263  delete[] reconParams;
    280 
    281 }
    282 
    283 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
     264}
     265
    284266Void TEncSampleAdaptiveOffset::getPreDBFStatistics(TComPic* pPic)
    285267{
     
    291273  for(Int n=0; n< m_numCTUsPic; n++)
    292274  {
    293     for(Int compIdx=0; compIdx < NUM_SAO_COMPONENTS; compIdx++)
     275    for(Int compIdx=0; compIdx < MAX_NUM_COMPONENT; compIdx++)
    294276    {
    295277      for(Int typeIdc=0; typeIdc < NUM_SAO_NEW_TYPES; typeIdc++)
     
    301283}
    302284
    303 #endif
    304 
    305 Void TEncSampleAdaptiveOffset::getStatistics(SAOStatData*** blkStats, TComPicYuv* orgYuv, TComPicYuv* srcYuv, TComPic* pPic
    306 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    307                           , Bool isCalculatePreDeblockSamples
    308 #endif
    309                           )
     285Void TEncSampleAdaptiveOffset::getStatistics(SAOStatData*** blkStats, TComPicYuv* orgYuv, TComPicYuv* srcYuv, TComPic* pPic, Bool isCalculatePreDeblockSamples)
    310286{
    311287  Bool isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail;
    312288
    313   for(Int ctu= 0; ctu < m_numCTUsPic; ctu++)
    314   {
    315     Int yPos   = (ctu / m_numCTUInWidth)*m_maxCUHeight;
    316     Int xPos   = (ctu % m_numCTUInWidth)*m_maxCUWidth;
     289  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
     290
     291  for(Int ctuRsAddr= 0; ctuRsAddr < m_numCTUsPic; ctuRsAddr++)
     292  {
     293    Int yPos   = (ctuRsAddr / m_numCTUInWidth)*m_maxCUHeight;
     294    Int xPos   = (ctuRsAddr % m_numCTUInWidth)*m_maxCUWidth;
    317295    Int height = (yPos + m_maxCUHeight > m_picHeight)?(m_picHeight- yPos):m_maxCUHeight;
    318296    Int width  = (xPos + m_maxCUWidth  > m_picWidth )?(m_picWidth - xPos):m_maxCUWidth;
    319297
    320     pPic->getPicSym()->deriveLoopFilterBoundaryAvailibility(ctu, isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail);
     298    pPic->getPicSym()->deriveLoopFilterBoundaryAvailibility(ctuRsAddr, isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail);
    321299
    322300    //NOTE: The number of skipped lines during gathering CTU statistics depends on the slice boundary availabilities.
     
    329307    isAboveRightAvail = ((yPos > 0) && (isRightAvail));
    330308
    331     for(Int compIdx=0; compIdx< NUM_SAO_COMPONENTS; compIdx++)
    332     {
    333       Bool isLuma     = (compIdx == SAO_Y);
    334       Int  formatShift= isLuma?0:1;
    335 
    336       Int  srcStride = isLuma?srcYuv->getStride():srcYuv->getCStride();
    337       Pel* srcBlk    = getPicBuf(srcYuv, compIdx)+ (yPos >> formatShift)*srcStride+ (xPos >> formatShift);
    338 
    339       Int  orgStride  = isLuma?orgYuv->getStride():orgYuv->getCStride();
    340       Pel* orgBlk     = getPicBuf(orgYuv, compIdx)+ (yPos >> formatShift)*orgStride+ (xPos >> formatShift);
    341 
    342       getBlkStats(compIdx, blkStats[ctu][compIdx] 
    343                 , srcBlk, orgBlk, srcStride, orgStride, (width  >> formatShift), (height >> formatShift)
    344                 , isLeftAvail,  isRightAvail, isAboveAvail, isBelowAvail, isAboveLeftAvail, isAboveRightAvail, isBelowLeftAvail, isBelowRightAvail
    345 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
     309    for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
     310    {
     311      const ComponentID component = ComponentID(compIdx);
     312
     313      const UInt componentScaleX = getComponentScaleX(component, pPic->getChromaFormat());
     314      const UInt componentScaleY = getComponentScaleY(component, pPic->getChromaFormat());
     315
     316      Int  srcStride  = srcYuv->getStride(component);
     317      Pel* srcBlk     = srcYuv->getAddr(component) + ((yPos >> componentScaleY) * srcStride) + (xPos >> componentScaleX);
     318
     319      Int  orgStride  = orgYuv->getStride(component);
     320      Pel* orgBlk     = orgYuv->getAddr(component) + ((yPos >> componentScaleY) * orgStride) + (xPos >> componentScaleX);
     321
     322      getBlkStats(component, pPic->getPicSym()->getSPS().getBitDepth(toChannelType(component)), blkStats[ctuRsAddr][component]
     323                , srcBlk, orgBlk, srcStride, orgStride, (width  >> componentScaleX), (height >> componentScaleY)
     324                , isLeftAvail,  isRightAvail, isAboveAvail, isBelowAvail, isAboveLeftAvail, isAboveRightAvail
    346325                , isCalculatePreDeblockSamples
    347 #endif
    348326                );
    349327
     
    352330}
    353331
    354 Void TEncSampleAdaptiveOffset::decidePicParams(Bool* sliceEnabled, Int picTempLayer)
     332Void TEncSampleAdaptiveOffset::decidePicParams(Bool* sliceEnabled, Int picTempLayer, const Double saoEncodingRate, const Double saoEncodingRateChroma)
    355333{
    356334  //decide sliceEnabled[compIdx]
    357   for (Int compIdx=0; compIdx<NUM_SAO_COMPONENTS; compIdx++)
     335  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
     336  for (Int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
     337  {
     338    sliceEnabled[compIdx] = false;
     339  }
     340
     341  for (Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
    358342  {
    359343    // reset flags & counters
    360344    sliceEnabled[compIdx] = true;
    361345
    362 #if SAO_ENCODING_CHOICE
    363 #if SAO_ENCODING_CHOICE_CHROMA
     346    if (saoEncodingRate>0.0)
     347    {
     348      if (saoEncodingRateChroma>0.0)
     349      {
    364350    // decide slice-level on/off based on previous results
    365     if( (picTempLayer > 0) 
    366       && (m_saoDisabledRate[compIdx][picTempLayer-1] > ((compIdx==SAO_Y) ? SAO_ENCODING_RATE : SAO_ENCODING_RATE_CHROMA)) )
     351    if( (picTempLayer > 0)
     352          && (m_saoDisabledRate[compIdx][picTempLayer-1] > ((compIdx==COMPONENT_Y) ? saoEncodingRate : saoEncodingRateChroma)) )
    367353    {
    368354      sliceEnabled[compIdx] = false;
    369355    }
    370 #else
     356      }
     357      else
     358      {
    371359    // decide slice-level on/off based on previous results
    372     if( (picTempLayer > 0) 
    373       && (m_saoDisabledRate[SAO_Y][0] > SAO_ENCODING_RATE) )
     360    if( (picTempLayer > 0)
     361          && (m_saoDisabledRate[COMPONENT_Y][0] > saoEncodingRate) )
    374362    {
    375363      sliceEnabled[compIdx] = false;
    376364    }
    377 #endif
    378 #endif
    379   }
    380 }
    381 
    382 Int64 TEncSampleAdaptiveOffset::getDistortion(Int ctu, Int compIdx, Int typeIdc, Int typeAuxInfo, Int* invQuantOffset, SAOStatData& statData)
    383 {
    384   Int64 dist=0;
    385   Int inputBitDepth    = (compIdx == SAO_Y) ? g_bitDepthY : g_bitDepthC ;
    386   Int shift = 2 * DISTORTION_PRECISION_ADJUSTMENT(inputBitDepth-8);
     365      }
     366    }
     367  }
     368}
     369
     370Int64 TEncSampleAdaptiveOffset::getDistortion(const Int channelBitDepth, Int typeIdc, Int typeAuxInfo, Int* invQuantOffset, SAOStatData& statData)
     371{
     372  Int64 dist        = 0;
     373  Int shift         = 2 * DISTORTION_PRECISION_ADJUSTMENT(channelBitDepth - 8);
    387374
    388375  switch(typeIdc)
     
    396383        {
    397384          dist += estSaoDist( statData.count[offsetIdx], invQuantOffset[offsetIdx], statData.diff[offsetIdx], shift);
    398         }       
     385        }
    399386      }
    400387      break;
     
    403390        for (Int offsetIdx=typeAuxInfo; offsetIdx<typeAuxInfo+4; offsetIdx++)
    404391        {
    405           Int bandIdx = offsetIdx % NUM_SAO_BO_CLASSES ; 
     392          Int bandIdx = offsetIdx % NUM_SAO_BO_CLASSES ;
    406393          dist += estSaoDist( statData.count[bandIdx], invQuantOffset[bandIdx], statData.diff[bandIdx], shift);
    407394        }
     
    425412
    426413
    427 inline Int TEncSampleAdaptiveOffset::estIterOffset(Int typeIdx, Int classIdx, Double lambda, Int offsetInput, Int64 count, Int64 diffSum, Int shift, Int bitIncrease, Int64& bestDist, Double& bestCost, Int offsetTh )
     414inline Int TEncSampleAdaptiveOffset::estIterOffset(Int typeIdx, Double lambda, Int offsetInput, Int64 count, Int64 diffSum, Int shift, Int bitIncrease, Int64& bestDist, Double& bestCost, Int offsetTh )
    428415{
    429416  Int iterOffset, tempOffset;
     
    432419  Int offsetOutput = 0;
    433420  iterOffset = offsetInput;
    434   // Assuming sending quantized value 0 results in zero offset and sending the value zero needs 1 bit. entropy coder can be used to measure the exact rate here. 
    435   tempMinCost = lambda; 
     421  // Assuming sending quantized value 0 results in zero offset and sending the value zero needs 1 bit. entropy coder can be used to measure the exact rate here.
     422  tempMinCost = lambda;
    436423  while (iterOffset != 0)
    437424  {
    438425    // Calculate the bits required for signaling the offset
    439     tempRate = (typeIdx == SAO_TYPE_BO) ? (abs((Int)iterOffset)+2) : (abs((Int)iterOffset)+1); 
    440     if (abs((Int)iterOffset)==offsetTh) //inclusive 
    441     { 
     426    tempRate = (typeIdx == SAO_TYPE_BO) ? (abs((Int)iterOffset)+2) : (abs((Int)iterOffset)+1);
     427    if (abs((Int)iterOffset)==offsetTh) //inclusive
     428    {
    442429      tempRate --;
    443430    }
     
    458445}
    459446
    460 
    461 Void TEncSampleAdaptiveOffset::deriveOffsets(Int ctu, Int compIdx, Int typeIdc, SAOStatData& statData, Int* quantOffsets, Int& typeAuxInfo)
    462 {
    463   Int bitDepth = (compIdx== SAO_Y) ? g_bitDepthY : g_bitDepthC;
    464   Int shift = 2 * DISTORTION_PRECISION_ADJUSTMENT(bitDepth-8);
    465   Int offsetTh = g_saoMaxOffsetQVal[compIdx];  //inclusive
     447Void TEncSampleAdaptiveOffset::deriveOffsets(ComponentID compIdx, const Int channelBitDepth, Int typeIdc, SAOStatData& statData, Int* quantOffsets, Int& typeAuxInfo)
     448{
     449  Int bitDepth = channelBitDepth;
     450  Int shift    = 2 * DISTORTION_PRECISION_ADJUSTMENT(bitDepth-8);
     451  Int offsetTh = TComSampleAdaptiveOffset::getMaxOffsetQVal(channelBitDepth);  //inclusive
    466452
    467453  ::memset(quantOffsets, 0, sizeof(Int)*MAX_NUM_SAO_CLASSES);
    468454
    469   //derive initial offsets 
     455  //derive initial offsets
    470456  Int numClasses = (typeIdc == SAO_TYPE_BO)?((Int)NUM_SAO_BO_CLASSES):((Int)NUM_SAO_EO_CLASSES);
    471457  for(Int classIdx=0; classIdx< numClasses; classIdx++)
    472458  {
    473     if( (typeIdc != SAO_TYPE_BO) && (classIdx==SAO_CLASS_EO_PLAIN)  ) 
     459    if( (typeIdc != SAO_TYPE_BO) && (classIdx==SAO_CLASS_EO_PLAIN)  )
    474460    {
    475461      continue; //offset will be zero
     
    481467    }
    482468
    483     quantOffsets[classIdx] = (Int) xRoundIbdi(bitDepth, (Double)( statData.diff[classIdx]<<(bitDepth-8)) 
    484                                                                   / 
     469    quantOffsets[classIdx] = (Int) xRoundIbdi(bitDepth, (Double)( statData.diff[classIdx]<<(bitDepth-8))
     470                                                                  /
    485471                                                          (Double)( statData.count[classIdx]<< m_offsetStepLog2[compIdx])
    486472                                               );
     
    498484        Int64 classDist;
    499485        Double classCost;
    500         for(Int classIdx=0; classIdx<NUM_SAO_EO_CLASSES; classIdx++) 
    501         {         
    502           if(classIdx==SAO_CLASS_EO_FULL_VALLEY && quantOffsets[classIdx] < 0) quantOffsets[classIdx] =0;
    503           if(classIdx==SAO_CLASS_EO_HALF_VALLEY && quantOffsets[classIdx] < 0) quantOffsets[classIdx] =0;
    504           if(classIdx==SAO_CLASS_EO_HALF_PEAK   && quantOffsets[classIdx] > 0) quantOffsets[classIdx] =0;
    505           if(classIdx==SAO_CLASS_EO_FULL_PEAK   && quantOffsets[classIdx] > 0) quantOffsets[classIdx] =0;
     486        for(Int classIdx=0; classIdx<NUM_SAO_EO_CLASSES; classIdx++)
     487        {
     488          if(classIdx==SAO_CLASS_EO_FULL_VALLEY && quantOffsets[classIdx] < 0)
     489          {
     490            quantOffsets[classIdx] =0;
     491          }
     492          if(classIdx==SAO_CLASS_EO_HALF_VALLEY && quantOffsets[classIdx] < 0)
     493          {
     494            quantOffsets[classIdx] =0;
     495          }
     496          if(classIdx==SAO_CLASS_EO_HALF_PEAK   && quantOffsets[classIdx] > 0)
     497          {
     498            quantOffsets[classIdx] =0;
     499          }
     500          if(classIdx==SAO_CLASS_EO_FULL_PEAK   && quantOffsets[classIdx] > 0)
     501          {
     502            quantOffsets[classIdx] =0;
     503          }
    506504
    507505          if( quantOffsets[classIdx] != 0 ) //iterative adjustment only when derived offset is not zero
    508506          {
    509             quantOffsets[classIdx] = estIterOffset( typeIdc, classIdx, m_lambda[compIdx], quantOffsets[classIdx], statData.count[classIdx], statData.diff[classIdx], shift, m_offsetStepLog2[compIdx], classDist , classCost , offsetTh );
    510           }
    511         }
    512      
     507            quantOffsets[classIdx] = estIterOffset( typeIdc, m_lambda[compIdx], quantOffsets[classIdx], statData.count[classIdx], statData.diff[classIdx], shift, m_offsetStepLog2[compIdx], classDist , classCost , offsetTh );
     508          }
     509        }
     510
    513511        typeAuxInfo =0;
    514512      }
     
    520518        ::memset(distBOClasses, 0, sizeof(Int64)*NUM_SAO_BO_CLASSES);
    521519        for(Int classIdx=0; classIdx< NUM_SAO_BO_CLASSES; classIdx++)
    522         {         
     520        {
    523521          costBOClasses[classIdx]= m_lambda[compIdx];
    524522          if( quantOffsets[classIdx] != 0 ) //iterative adjustment only when derived offset is not zero
    525523          {
    526             quantOffsets[classIdx] = estIterOffset( typeIdc, classIdx, m_lambda[compIdx], quantOffsets[classIdx], statData.count[classIdx], statData.diff[classIdx], shift, m_offsetStepLog2[compIdx], distBOClasses[classIdx], costBOClasses[classIdx], offsetTh );
     524            quantOffsets[classIdx] = estIterOffset( typeIdc, m_lambda[compIdx], quantOffsets[classIdx], statData.count[classIdx], statData.diff[classIdx], shift, m_offsetStepLog2[compIdx], distBOClasses[classIdx], costBOClasses[classIdx], offsetTh );
    527525          }
    528526        }
     
    530528        //decide the starting band index
    531529        Double minCost = MAX_DOUBLE, cost;
    532         for(Int band=0; band< NUM_SAO_BO_CLASSES- 4+ 1; band++) 
     530        for(Int band=0; band< NUM_SAO_BO_CLASSES- 4+ 1; band++)
    533531        {
    534532          cost  = costBOClasses[band  ];
     
    546544        Int clearQuantOffset[NUM_SAO_BO_CLASSES];
    547545        ::memset(clearQuantOffset, 0, sizeof(Int)*NUM_SAO_BO_CLASSES);
    548         for(Int i=0; i< 4; i++) 
     546        for(Int i=0; i< 4; i++)
    549547        {
    550548          Int band = (typeAuxInfo+i)%NUM_SAO_BO_CLASSES;
    551549          clearQuantOffset[band] = quantOffsets[band];
    552550        }
    553         ::memcpy(quantOffsets, clearQuantOffset, sizeof(Int)*NUM_SAO_BO_CLASSES);       
     551        ::memcpy(quantOffsets, clearQuantOffset, sizeof(Int)*NUM_SAO_BO_CLASSES);
    554552      }
    555553      break;
     
    566564}
    567565
    568 
    569 Void TEncSampleAdaptiveOffset::deriveModeNewRDO(Int ctu, std::vector<SAOBlkParam*>& mergeList, Bool* sliceEnabled, SAOStatData*** blkStats, SAOBlkParam& modeParam, Double& modeNormCost, TEncSbac** cabacCoderRDO, Int inCabacLabel)
     566Void TEncSampleAdaptiveOffset::deriveModeNewRDO(const BitDepths &bitDepths, Int ctuRsAddr, SAOBlkParam* mergeList[NUM_SAO_MERGE_TYPES], Bool* sliceEnabled, SAOStatData*** blkStats, SAOBlkParam& modeParam, Double& modeNormCost, TEncSbac** cabacCoderRDO, Int inCabacLabel)
    570567{
    571568  Double minCost, cost;
    572   Int rate;
    573569  UInt previousWrittenBits;
    574   Int64 dist[NUM_SAO_COMPONENTS], modeDist[NUM_SAO_COMPONENTS];
    575   SAOOffset testOffset[NUM_SAO_COMPONENTS];
    576   Int compIdx;
     570  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
     571
     572  Int64 dist[MAX_NUM_COMPONENT], modeDist[MAX_NUM_COMPONENT];
     573  SAOOffset testOffset[MAX_NUM_COMPONENT];
    577574  Int invQuantOffset[MAX_NUM_SAO_CLASSES];
    578 
    579   modeDist[SAO_Y]= modeDist[SAO_Cb] = modeDist[SAO_Cr] = 0;
     575  for(Int comp=0; comp < MAX_NUM_COMPONENT; comp++)
     576  {
     577    modeDist[comp] = 0;
     578  }
    580579
    581580  //pre-encode merge flags
    582   modeParam[SAO_Y ].modeIdc = SAO_MODE_OFF;
     581  modeParam[COMPONENT_Y].modeIdc = SAO_MODE_OFF;
    583582  m_pcRDGoOnSbacCoder->load(cabacCoderRDO[inCabacLabel]);
    584   m_pcRDGoOnSbacCoder->codeSAOBlkParam(modeParam, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), true);
     583  m_pcRDGoOnSbacCoder->codeSAOBlkParam(modeParam, bitDepths, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), true);
    585584  m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_MID]);
    586585
    587   //------ luma --------//
    588   compIdx = SAO_Y;
    589   //"off" case as initial cost
    590   modeParam[compIdx].modeIdc = SAO_MODE_OFF;
    591   m_pcRDGoOnSbacCoder->resetBits();
    592   m_pcRDGoOnSbacCoder->codeSAOOffsetParam(compIdx, modeParam[compIdx], sliceEnabled[compIdx]);
    593   modeDist[compIdx] = 0;
    594   minCost= m_lambda[compIdx]*((Double)m_pcRDGoOnSbacCoder->getNumberOfWrittenBits());
    595   m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
    596   if(sliceEnabled[compIdx])
    597   {
    598     for(Int typeIdc=0; typeIdc< NUM_SAO_NEW_TYPES; typeIdc++)
    599     {
    600       testOffset[compIdx].modeIdc = SAO_MODE_NEW;
    601       testOffset[compIdx].typeIdc = typeIdc;
    602 
    603       //derive coded offset
    604       deriveOffsets(ctu, compIdx, typeIdc, blkStats[ctu][compIdx][typeIdc], testOffset[compIdx].offset, testOffset[compIdx].typeAuxInfo);
    605 
    606       //inversed quantized offsets
    607       invertQuantOffsets(compIdx, typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, testOffset[compIdx].offset);
    608 
    609       //get distortion
    610       dist[compIdx] = getDistortion(ctu, compIdx, testOffset[compIdx].typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, blkStats[ctu][compIdx][typeIdc]);
    611 
    612       //get rate
    613       m_pcRDGoOnSbacCoder->load(cabacCoderRDO[SAO_CABACSTATE_BLK_MID]);
    614       m_pcRDGoOnSbacCoder->resetBits();
    615       m_pcRDGoOnSbacCoder->codeSAOOffsetParam(compIdx, testOffset[compIdx], sliceEnabled[compIdx]);
    616       rate = m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
    617       cost = (Double)dist[compIdx] + m_lambda[compIdx]*((Double)rate);
    618       if(cost < minCost)
    619       {
    620         minCost = cost;
    621         modeDist[compIdx] = dist[compIdx];
    622         modeParam[compIdx]= testOffset[compIdx];
    623         m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
    624       }
    625     }
    626   }
    627   m_pcRDGoOnSbacCoder->load(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
    628   m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_MID]);
     586    //------ luma --------//
     587  {
     588    const ComponentID compIdx = COMPONENT_Y;
     589    //"off" case as initial cost
     590    modeParam[compIdx].modeIdc = SAO_MODE_OFF;
     591    m_pcRDGoOnSbacCoder->resetBits();
     592    m_pcRDGoOnSbacCoder->codeSAOOffsetParam(compIdx, modeParam[compIdx], sliceEnabled[compIdx], bitDepths.recon[CHANNEL_TYPE_LUMA]);
     593    modeDist[compIdx] = 0;
     594    minCost= m_lambda[compIdx]*((Double)m_pcRDGoOnSbacCoder->getNumberOfWrittenBits());
     595    m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
     596    if(sliceEnabled[compIdx])
     597    {
     598      for(Int typeIdc=0; typeIdc< NUM_SAO_NEW_TYPES; typeIdc++)
     599      {
     600        testOffset[compIdx].modeIdc = SAO_MODE_NEW;
     601        testOffset[compIdx].typeIdc = typeIdc;
     602
     603        //derive coded offset
     604        deriveOffsets(compIdx, bitDepths.recon[CHANNEL_TYPE_LUMA], typeIdc, blkStats[ctuRsAddr][compIdx][typeIdc], testOffset[compIdx].offset, testOffset[compIdx].typeAuxInfo);
     605
     606        //inversed quantized offsets
     607        invertQuantOffsets(compIdx, typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, testOffset[compIdx].offset);
     608
     609        //get distortion
     610        dist[compIdx] = getDistortion(bitDepths.recon[CHANNEL_TYPE_LUMA], testOffset[compIdx].typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, blkStats[ctuRsAddr][compIdx][typeIdc]);
     611
     612        //get rate
     613        m_pcRDGoOnSbacCoder->load(cabacCoderRDO[SAO_CABACSTATE_BLK_MID]);
     614        m_pcRDGoOnSbacCoder->resetBits();
     615        m_pcRDGoOnSbacCoder->codeSAOOffsetParam(compIdx, testOffset[compIdx], sliceEnabled[compIdx], bitDepths.recon[CHANNEL_TYPE_LUMA]);
     616        Int rate = m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
     617        cost = (Double)dist[compIdx] + m_lambda[compIdx]*((Double)rate);
     618        if(cost < minCost)
     619        {
     620          minCost = cost;
     621          modeDist[compIdx] = dist[compIdx];
     622          modeParam[compIdx]= testOffset[compIdx];
     623          m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
     624        }
     625      }
     626    }
     627    m_pcRDGoOnSbacCoder->load(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
     628    m_pcRDGoOnSbacCoder->store(cabacCoderRDO[SAO_CABACSTATE_BLK_MID]);
     629  }
    629630
    630631  //------ chroma --------//
    631   //"off" case as initial cost
     632//"off" case as initial cost
    632633  cost = 0;
    633634  previousWrittenBits = 0;
    634635  m_pcRDGoOnSbacCoder->resetBits();
    635   for (Int component = SAO_Cb; component < NUM_SAO_COMPONENTS; component++)
    636   {
    637     modeParam[component].modeIdc = SAO_MODE_OFF;
    638     modeDist [component] = 0;
    639 
    640     m_pcRDGoOnSbacCoder->codeSAOOffsetParam(component, modeParam[component], sliceEnabled[component]);
    641 
     636  for(UInt componentIndex = COMPONENT_Cb; componentIndex < numberOfComponents; componentIndex++)
     637  {
     638    const ComponentID component = ComponentID(componentIndex);
     639
     640    modeParam[component].modeIdc = SAO_MODE_OFF;
     641    modeDist [component]         = 0;
     642    m_pcRDGoOnSbacCoder->codeSAOOffsetParam(component, modeParam[component], sliceEnabled[component], bitDepths.recon[CHANNEL_TYPE_CHROMA]);
     643   
    642644    const UInt currentWrittenBits = m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
    643645    cost += m_lambda[component] * (currentWrittenBits - previousWrittenBits);
     
    656658    cost = 0;
    657659
    658     for(compIdx= SAO_Cb; compIdx< NUM_SAO_COMPONENTS; compIdx++)
    659     {
    660       if(!sliceEnabled[compIdx])
    661       {
    662         testOffset[compIdx].modeIdc = SAO_MODE_OFF;
    663         dist[compIdx]= 0;
     660    for(UInt componentIndex = COMPONENT_Cb; componentIndex < numberOfComponents; componentIndex++)
     661    {
     662      const ComponentID component = ComponentID(componentIndex);
     663      if(!sliceEnabled[component])
     664      {
     665        testOffset[component].modeIdc = SAO_MODE_OFF;
     666        dist[component]= 0;
    664667        continue;
    665668      }
    666       testOffset[compIdx].modeIdc = SAO_MODE_NEW;
    667       testOffset[compIdx].typeIdc = typeIdc;
     669      testOffset[component].modeIdc = SAO_MODE_NEW;
     670      testOffset[component].typeIdc = typeIdc;
    668671
    669672      //derive offset & get distortion
    670       deriveOffsets(ctu, compIdx, typeIdc, blkStats[ctu][compIdx][typeIdc], testOffset[compIdx].offset, testOffset[compIdx].typeAuxInfo);
    671       invertQuantOffsets(compIdx, typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, testOffset[compIdx].offset);
    672       dist[compIdx]= getDistortion(ctu, compIdx, typeIdc, testOffset[compIdx].typeAuxInfo, invQuantOffset, blkStats[ctu][compIdx][typeIdc]);
    673      
    674       m_pcRDGoOnSbacCoder->codeSAOOffsetParam(compIdx, testOffset[compIdx], sliceEnabled[compIdx]);
     673      deriveOffsets(component, bitDepths.recon[CHANNEL_TYPE_CHROMA], typeIdc, blkStats[ctuRsAddr][component][typeIdc], testOffset[component].offset, testOffset[component].typeAuxInfo);
     674      invertQuantOffsets(component, typeIdc, testOffset[component].typeAuxInfo, invQuantOffset, testOffset[component].offset);
     675      dist[component] = getDistortion(bitDepths.recon[CHANNEL_TYPE_CHROMA], typeIdc, testOffset[component].typeAuxInfo, invQuantOffset, blkStats[ctuRsAddr][component][typeIdc]);
     676
     677      m_pcRDGoOnSbacCoder->codeSAOOffsetParam(component, testOffset[component], sliceEnabled[component], bitDepths.recon[CHANNEL_TYPE_CHROMA]);
    675678
    676679      const UInt currentWrittenBits = m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
    677       cost += dist[compIdx] + (m_lambda[compIdx] * (currentWrittenBits - previousWrittenBits));
     680      cost += dist[component] + (m_lambda[component] * (currentWrittenBits - previousWrittenBits));
    678681      previousWrittenBits = currentWrittenBits;
    679682    }
     
    682685    {
    683686      minCost = cost;
    684       for(compIdx= SAO_Cb; compIdx< NUM_SAO_COMPONENTS; compIdx++)
    685       {
    686         modeDist [compIdx] = dist      [compIdx];
    687         modeParam[compIdx] = testOffset[compIdx];
    688       }
    689     }
    690   }
    691 
     687      for(UInt componentIndex = COMPONENT_Cb; componentIndex < numberOfComponents; componentIndex++)
     688      {
     689        modeDist[componentIndex]  = dist[componentIndex];
     690        modeParam[componentIndex] = testOffset[componentIndex];
     691      }
     692    }
     693
     694  } // SAO_TYPE loop
    692695
    693696  //----- re-gen rate & normalized cost----//
    694697  modeNormCost = 0;
    695   for(UInt component = SAO_Y; component < NUM_SAO_COMPONENTS; component++)
    696   {
    697     modeNormCost += (Double)modeDist[component] / m_lambda[component];
    698   }
     698  for(UInt componentIndex = COMPONENT_Y; componentIndex < numberOfComponents; componentIndex++)
     699  {
     700    modeNormCost += (Double)modeDist[componentIndex] / m_lambda[componentIndex];
     701  }
     702
    699703  m_pcRDGoOnSbacCoder->load(cabacCoderRDO[inCabacLabel]);
    700704  m_pcRDGoOnSbacCoder->resetBits();
    701   m_pcRDGoOnSbacCoder->codeSAOBlkParam(modeParam, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), false);
     705  m_pcRDGoOnSbacCoder->codeSAOBlkParam(modeParam, bitDepths, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), false);
    702706  modeNormCost += (Double)m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
    703 
    704 }
    705 
    706 Void TEncSampleAdaptiveOffset::deriveModeMergeRDO(Int ctu, std::vector<SAOBlkParam*>& mergeList, Bool* sliceEnabled, SAOStatData*** blkStats, SAOBlkParam& modeParam, Double& modeNormCost, TEncSbac** cabacCoderRDO, Int inCabacLabel)
    707 {
    708   Int mergeListSize = (Int)mergeList.size();
     707}
     708
     709Void TEncSampleAdaptiveOffset::deriveModeMergeRDO(const BitDepths &bitDepths, Int ctuRsAddr, SAOBlkParam* mergeList[NUM_SAO_MERGE_TYPES], Bool* sliceEnabled, SAOStatData*** blkStats, SAOBlkParam& modeParam, Double& modeNormCost, TEncSbac** cabacCoderRDO, Int inCabacLabel)
     710{
    709711  modeNormCost = MAX_DOUBLE;
    710712
    711713  Double cost;
    712714  SAOBlkParam testBlkParam;
    713 
    714   for(Int mergeType=0; mergeType< mergeListSize; mergeType++)
     715  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
     716
     717  for(Int mergeType=0; mergeType< NUM_SAO_MERGE_TYPES; mergeType++)
    715718  {
    716719    if(mergeList[mergeType] == NULL)
     
    722725    //normalized distortion
    723726    Double normDist=0;
    724     for(Int compIdx=0; compIdx< NUM_SAO_COMPONENTS; compIdx++)
     727    for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
    725728    {
    726729      testBlkParam[compIdx].modeIdc = SAO_MODE_MERGE;
     
    732735      {
    733736        //offsets have been reconstructed. Don't call inversed quantization function.
    734         normDist += (((Double)getDistortion(ctu, compIdx, mergedOffsetParam.typeIdc, mergedOffsetParam.typeAuxInfo, mergedOffsetParam.offset, blkStats[ctu][compIdx][mergedOffsetParam.typeIdc]))
     737        normDist += (((Double)getDistortion(bitDepths.recon[toChannelType(ComponentID(compIdx))], mergedOffsetParam.typeIdc, mergedOffsetParam.typeAuxInfo, mergedOffsetParam.offset, blkStats[ctuRsAddr][compIdx][mergedOffsetParam.typeIdc]))
    735738                       /m_lambda[compIdx]
    736739                    );
     
    742745    m_pcRDGoOnSbacCoder->load(cabacCoderRDO[inCabacLabel]);
    743746    m_pcRDGoOnSbacCoder->resetBits();
    744     m_pcRDGoOnSbacCoder->codeSAOBlkParam(testBlkParam, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), false);
     747    m_pcRDGoOnSbacCoder->codeSAOBlkParam(testBlkParam, bitDepths, sliceEnabled, (mergeList[SAO_MERGE_LEFT]!= NULL), (mergeList[SAO_MERGE_ABOVE]!= NULL), false);
    745748    Int rate = m_pcRDGoOnSbacCoder->getNumberOfWrittenBits();
    746749
     
    756759
    757760  m_pcRDGoOnSbacCoder->load(cabacCoderRDO[SAO_CABACSTATE_BLK_TEMP]);
    758 
    759 
    760 }
    761 
    762 Void TEncSampleAdaptiveOffset::decideBlkParams(TComPic* pic, Bool* sliceEnabled, SAOStatData*** blkStats, TComPicYuv* srcYuv, TComPicYuv* resYuv, SAOBlkParam* reconParams, SAOBlkParam* codedParams)
    763 {
    764   Bool isAllBlksDisabled = false;
    765   if(!sliceEnabled[SAO_Y] && !sliceEnabled[SAO_Cb] && !sliceEnabled[SAO_Cr])
    766   {
    767     isAllBlksDisabled = true;
     761}
     762
     763Void TEncSampleAdaptiveOffset::decideBlkParams(TComPic* pic, Bool* sliceEnabled, SAOStatData*** blkStats, TComPicYuv* srcYuv, TComPicYuv* resYuv,
     764                                               SAOBlkParam* reconParams, SAOBlkParam* codedParams, const Bool bTestSAODisableAtPictureLevel,
     765                                               const Double saoEncodingRate, const Double saoEncodingRateChroma)
     766{
     767  Bool allBlksDisabled = true;
     768  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
     769  for(Int compId = COMPONENT_Y; compId < numberOfComponents; compId++)
     770  {
     771    if (sliceEnabled[compId])
     772    {
     773      allBlksDisabled = false;
     774    }
    768775  }
    769776
     
    773780  Double minCost, modeCost;
    774781
    775   for(Int ctu=0; ctu< m_numCTUsPic; ctu++)
    776   {
    777     if(isAllBlksDisabled)
    778     {
    779       codedParams[ctu].reset();
     782
     783  Double totalCost = 0; // Used if bTestSAODisableAtPictureLevel==true
     784
     785  for(Int ctuRsAddr=0; ctuRsAddr< m_numCTUsPic; ctuRsAddr++)
     786  {
     787    if(allBlksDisabled)
     788    {
     789      codedParams[ctuRsAddr].reset();
    780790      continue;
    781791    }
     
    784794
    785795    //get merge list
    786     std::vector<SAOBlkParam*> mergeList;
    787     getMergeList(pic, ctu, reconParams, mergeList);
     796    SAOBlkParam* mergeList[NUM_SAO_MERGE_TYPES] = { NULL };
     797    getMergeList(pic, ctuRsAddr, reconParams, mergeList);
    788798
    789799    minCost = MAX_DOUBLE;
     
    799809      case SAO_MODE_NEW:
    800810        {
    801           deriveModeNewRDO(ctu, mergeList, sliceEnabled, blkStats, modeParam, modeCost, m_pppcRDSbacCoder, SAO_CABACSTATE_BLK_CUR);
     811          deriveModeNewRDO(pic->getPicSym()->getSPS().getBitDepths(), ctuRsAddr, mergeList, sliceEnabled, blkStats, modeParam, modeCost, m_pppcRDSbacCoder, SAO_CABACSTATE_BLK_CUR);
    802812
    803813        }
     
    805815      case SAO_MODE_MERGE:
    806816        {
    807           deriveModeMergeRDO(ctu, mergeList, sliceEnabled, blkStats , modeParam, modeCost, m_pppcRDSbacCoder, SAO_CABACSTATE_BLK_CUR);
     817          deriveModeMergeRDO(pic->getPicSym()->getSPS().getBitDepths(), ctuRsAddr, mergeList, sliceEnabled, blkStats , modeParam, modeCost, m_pppcRDSbacCoder, SAO_CABACSTATE_BLK_CUR);
    808818        }
    809819        break;
     
    816826      }
    817827
     828      D_PRINT_INDENT( g_traceSAOCost, "SAO mode " + n2s( mode ) + " Cost:  " + n2s( modeCost) );
     829
    818830      if(modeCost < minCost)
    819831      {
    820832        minCost = modeCost;
    821         codedParams[ctu] = modeParam;
     833        codedParams[ctuRsAddr] = modeParam;
    822834        m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[ SAO_CABACSTATE_BLK_NEXT ]);
    823 
    824835      }
    825836    } //mode
     837
     838    totalCost += minCost;
     839
    826840    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[ SAO_CABACSTATE_BLK_NEXT ]);
    827841
    828842    //apply reconstructed offsets
    829     reconParams[ctu] = codedParams[ctu];
    830     reconstructBlkSAOParam(reconParams[ctu], mergeList);
    831     offsetCTU(ctu, srcYuv, resYuv, reconParams[ctu], pic);
    832   } //ctu
    833 
    834 #if SAO_ENCODING_CHOICE
     843    reconParams[ctuRsAddr] = codedParams[ctuRsAddr];
     844    reconstructBlkSAOParam(reconParams[ctuRsAddr], mergeList);
     845    offsetCTU(ctuRsAddr, srcYuv, resYuv, reconParams[ctuRsAddr], pic);
     846  } //ctuRsAddr
     847
     848  if (!allBlksDisabled && (totalCost >= 0) && bTestSAODisableAtPictureLevel) //SAO has not beneficial in this case - disable it
     849  {
     850    for(Int ctuRsAddr = 0; ctuRsAddr < m_numCTUsPic; ctuRsAddr++)
     851    {
     852      codedParams[ctuRsAddr].reset();
     853    }
     854
     855    for (UInt componentIndex = 0; componentIndex < MAX_NUM_COMPONENT; componentIndex++)
     856    {
     857      sliceEnabled[componentIndex] = false;
     858    }
     859
     860    m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[ SAO_CABACSTATE_PIC_INIT ]);
     861  }
     862
     863  if (saoEncodingRate > 0.0)
     864  {
    835865  Int picTempLayer = pic->getSlice(0)->getDepth();
    836   Int numLcusForSAOOff[NUM_SAO_COMPONENTS];
    837   numLcusForSAOOff[SAO_Y ] = numLcusForSAOOff[SAO_Cb]= numLcusForSAOOff[SAO_Cr]= 0;
    838 
    839   for (Int compIdx=0; compIdx<NUM_SAO_COMPONENTS; compIdx++)
    840   {
    841     for(Int ctu=0; ctu< m_numCTUsPic; ctu++)
    842     {
    843       if( reconParams[ctu][compIdx].modeIdc == SAO_MODE_OFF)
    844       {
    845         numLcusForSAOOff[compIdx]++;
    846       }
    847     }
    848   }
    849 #if SAO_ENCODING_CHOICE_CHROMA
    850   for (Int compIdx=0; compIdx<NUM_SAO_COMPONENTS; compIdx++)
    851   {
    852     m_saoDisabledRate[compIdx][picTempLayer] = (Double)numLcusForSAOOff[compIdx]/(Double)m_numCTUsPic;
    853   }
    854 #else
    855   if (picTempLayer == 0)
    856   {
    857     m_saoDisabledRate[SAO_Y][0] = (Double)(numLcusForSAOOff[SAO_Y]+numLcusForSAOOff[SAO_Cb]+numLcusForSAOOff[SAO_Cr])/(Double)(m_numCTUsPic*3);
    858   }
    859 #endif                                             
    860 #endif
    861 }
    862 
    863 
    864 Void TEncSampleAdaptiveOffset::getBlkStats(Int compIdx, SAOStatData* statsDataTypes 
     866  Int numCtusForSAOOff[MAX_NUM_COMPONENT];
     867
     868  for (Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
     869  {
     870    numCtusForSAOOff[compIdx] = 0;
     871    for(Int ctuRsAddr=0; ctuRsAddr< m_numCTUsPic; ctuRsAddr++)
     872    {
     873      if( reconParams[ctuRsAddr][compIdx].modeIdc == SAO_MODE_OFF)
     874      {
     875        numCtusForSAOOff[compIdx]++;
     876      }
     877    }
     878  }
     879    if (saoEncodingRateChroma > 0.0)
     880    {
     881  for (Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
     882  {
     883    m_saoDisabledRate[compIdx][picTempLayer] = (Double)numCtusForSAOOff[compIdx]/(Double)m_numCTUsPic;
     884  }
     885    }
     886    else if (picTempLayer == 0)
     887  {
     888    m_saoDisabledRate[COMPONENT_Y][0] = (Double)(numCtusForSAOOff[COMPONENT_Y]+numCtusForSAOOff[COMPONENT_Cb]+numCtusForSAOOff[COMPONENT_Cr])/(Double)(m_numCTUsPic*3);
     889  }
     890  }
     891}
     892
     893
     894Void TEncSampleAdaptiveOffset::getBlkStats(const ComponentID compIdx, const Int channelBitDepth, SAOStatData* statsDataTypes
    865895                        , Pel* srcBlk, Pel* orgBlk, Int srcStride, Int orgStride, Int width, Int height
    866                         , Bool isLeftAvail,  Bool isRightAvail, Bool isAboveAvail, Bool isBelowAvail, Bool isAboveLeftAvail, Bool isAboveRightAvail, Bool isBelowLeftAvail, Bool isBelowRightAvail
    867 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
     896                        , Bool isLeftAvail,  Bool isRightAvail, Bool isAboveAvail, Bool isBelowAvail, Bool isAboveLeftAvail, Bool isAboveRightAvail
    868897                        , Bool isCalculatePreDeblockSamples
    869 #endif
    870898                        )
    871899{
     
    874902    m_lineBufWidth = m_maxCUWidth;
    875903
    876     if (m_signLineBuf1) delete[] m_signLineBuf1; m_signLineBuf1 = NULL;
    877     m_signLineBuf1 = new Char[m_lineBufWidth+1];
    878 
    879     if (m_signLineBuf2) delete[] m_signLineBuf2; m_signLineBuf2 = NULL;
     904    if (m_signLineBuf1)
     905    {
     906      delete[] m_signLineBuf1;
     907      m_signLineBuf1 = NULL;
     908    }
     909    m_signLineBuf1 = new Char[m_lineBufWidth+1];
     910
     911    if (m_signLineBuf2)
     912    {
     913      delete[] m_signLineBuf2;
     914      m_signLineBuf2 = NULL;
     915    }
    880916    m_signLineBuf2 = new Char[m_lineBufWidth+1];
    881917  }
     
    904940        count+=2;
    905941        endY   = (isBelowAvail) ? (height - skipLinesB[typeIdx]) : height;
    906 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    907942        startX = (!isCalculatePreDeblockSamples) ? (isLeftAvail  ? 0 : 1)
    908943                                                 : (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1))
    909944                                                 ;
    910 #else
    911         startX = isLeftAvail ? 0 : 1;
    912 #endif
    913 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    914945        endX   = (!isCalculatePreDeblockSamples) ? (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1))
    915946                                                 : (isRightAvail ? width : (width - 1))
    916947                                                 ;
    917 #else
    918         endX   = isRightAvail ? (width - skipLinesR[typeIdx]): (width - 1);
    919 #endif
    920948        for (y=0; y<endY; y++)
    921949        {
    922 #if SAO_SGN_FUNC
    923950          signLeft = (Char)sgn(srcLine[startX] - srcLine[startX-1]);
    924 #else
    925           signLeft = (Char)m_sign[srcLine[startX] - srcLine[startX-1]];
    926 #endif
    927951          for (x=startX; x<endX; x++)
    928952          {
    929 #if SAO_SGN_FUNC
    930953            signRight =  (Char)sgn(srcLine[x] - srcLine[x+1]);
    931 #else
    932             signRight =  (Char)m_sign[srcLine[x] - srcLine[x+1]];
    933 #endif
    934954            edgeType  =  signRight + signLeft;
    935955            signLeft  = -signRight;
     
    941961          orgLine  += orgStride;
    942962        }
    943 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    944963        if(isCalculatePreDeblockSamples)
    945964        {
     
    951970            for(y=0; y<skipLinesB[typeIdx]; y++)
    952971            {
    953 #if SAO_SGN_FUNC
    954972              signLeft = (Char)sgn(srcLine[startX] - srcLine[startX-1]);
    955 #else
    956               signLeft = (Char)m_sign[srcLine[startX] - srcLine[startX-1]];
    957 #endif
    958973              for (x=startX; x<endX; x++)
    959974              {
    960 #if SAO_SGN_FUNC
    961975                signRight =  (Char)sgn(srcLine[x] - srcLine[x+1]);
    962 #else
    963                 signRight =  (Char)m_sign[srcLine[x] - srcLine[x+1]];
    964 #endif
    965976                edgeType  =  signRight + signLeft;
    966977                signLeft  = -signRight;
     
    974985          }
    975986        }
    976 #endif
    977987      }
    978988      break;
     
    983993        Char *signUpLine = m_signLineBuf1;
    984994
    985 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    986995        startX = (!isCalculatePreDeblockSamples) ? 0
    987996                                                 : (isRightAvail ? (width - skipLinesR[typeIdx]) : width)
    988997                                                 ;
    989 #endif
    990998        startY = isAboveAvail ? 0 : 1;
    991 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    992         endX   = (!isCalculatePreDeblockSamples) ? (isRightAvail ? (width - skipLinesR[typeIdx]) : width)
     999        endX   = (!isCalculatePreDeblockSamples) ? (isRightAvail ? (width - skipLinesR[typeIdx]) : width)
    9931000                                                 : width
    9941001                                                 ;
    995 #else
    996         endX   = isRightAvail ? (width - skipLinesR[typeIdx]) : width ;
    997 #endif
    9981002        endY   = isBelowAvail ? (height - skipLinesB[typeIdx]) : (height - 1);
    9991003        if (!isAboveAvail)
     
    10041008
    10051009        Pel* srcLineAbove = srcLine - srcStride;
    1006 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    1007         for (x=startX; x<endX; x++)
    1008 #else
    1009         for (x=0; x< endX; x++)
    1010 #endif
    1011         {
    1012 #if SAO_SGN_FUNC
     1010        for (x=startX; x<endX; x++)
     1011        {
    10131012          signUpLine[x] = (Char)sgn(srcLine[x] - srcLineAbove[x]);
    1014 #else
    1015           signUpLine[x] = (Char)m_sign[srcLine[x] - srcLineAbove[x]];
    1016 #endif
    10171013        }
    10181014
     
    10221018          srcLineBelow = srcLine + srcStride;
    10231019
    1024 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    10251020          for (x=startX; x<endX; x++)
    1026 #else
    1027           for (x=0; x<endX; x++)
    1028 #endif
    1029           {
    1030 #if SAO_SGN_FUNC
     1021          {
    10311022            signDown  = (Char)sgn(srcLine[x] - srcLineBelow[x]);
    1032 #else
    1033             signDown  = (Char)m_sign[srcLine[x] - srcLineBelow[x]];
    1034 #endif
    10351023            edgeType  = signDown + signUpLine[x];
    10361024            signUpLine[x]= -signDown;
     
    10421030          orgLine += orgStride;
    10431031        }
    1044 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    10451032        if(isCalculatePreDeblockSamples)
    10461033        {
     
    10571044              for (x=startX; x<endX; x++)
    10581045              {
    1059 #if SAO_SGN_FUNC
    10601046                edgeType = sgn(srcLine[x] - srcLineBelow[x]) + sgn(srcLine[x] - srcLineAbove[x]);
    1061 #else
    1062                 edgeType = m_sign[srcLine[x] - srcLineBelow[x]] + m_sign[srcLine[x] - srcLineAbove[x]];
    1063 #endif
    10641047                diff [edgeType] += (orgLine[x] - srcLine[x]);
    10651048                count[edgeType] ++;
     
    10701053          }
    10711054        }
    1072 #endif
    10731055
    10741056      }
     
    10831065        signDownLine= m_signLineBuf2;
    10841066
    1085 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    10861067        startX = (!isCalculatePreDeblockSamples) ? (isLeftAvail  ? 0 : 1)
    10871068                                                 : (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1))
    10881069                                                 ;
    1089 #else
    1090         startX = isLeftAvail ? 0 : 1 ;
    1091 #endif
    1092 
    1093 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
     1070
    10941071        endX   = (!isCalculatePreDeblockSamples) ? (isRightAvail ? (width - skipLinesR[typeIdx]): (width - 1))
    10951072                                                 : (isRightAvail ? width : (width - 1))
    10961073                                                 ;
    1097 #else
    1098         endX   = isRightAvail ? (width - skipLinesR[typeIdx]): (width - 1);
    1099 #endif
    11001074        endY   = isBelowAvail ? (height - skipLinesB[typeIdx]) : (height - 1);
    11011075
     
    11041078        for (x=startX; x<endX+1; x++)
    11051079        {
    1106 #if SAO_SGN_FUNC
    11071080          signUpLine[x] = (Char)sgn(srcLineBelow[x] - srcLine[x-1]);
    1108 #else
    1109           signUpLine[x] = (Char)m_sign[srcLineBelow[x] - srcLine[x-1]];
    1110 #endif
    11111081        }
    11121082
    11131083        //1st line
    11141084        Pel* srcLineAbove = srcLine - srcStride;
    1115 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    11161085        firstLineStartX = (!isCalculatePreDeblockSamples) ? (isAboveLeftAvail ? 0    : 1) : startX;
    11171086        firstLineEndX   = (!isCalculatePreDeblockSamples) ? (isAboveAvail     ? endX : 1) : endX;
    1118 #else
    1119         firstLineStartX = isAboveLeftAvail ? 0    : 1;
    1120         firstLineEndX   = isAboveAvail     ? endX : 1;
    1121 #endif
    11221087        for(x=firstLineStartX; x<firstLineEndX; x++)
    11231088        {
    1124 #if SAO_SGN_FUNC
    11251089          edgeType = sgn(srcLine[x] - srcLineAbove[x-1]) - signUpLine[x+1];
    1126 #else
    1127           edgeType = m_sign[srcLine[x] - srcLineAbove[x-1]] - signUpLine[x+1];
    1128 #endif
    11291090          diff [edgeType] += (orgLine[x] - srcLine[x]);
    11301091          count[edgeType] ++;
     
    11411102          for (x=startX; x<endX; x++)
    11421103          {
    1143 #if SAO_SGN_FUNC
    11441104            signDown = (Char)sgn(srcLine[x] - srcLineBelow[x+1]);
    1145 #else
    1146             signDown = (Char)m_sign[srcLine[x] - srcLineBelow[x+1]] ;
    1147 #endif
    11481105            edgeType = signDown + signUpLine[x];
    11491106            diff [edgeType] += (orgLine[x] - srcLine[x]);
    11501107            count[edgeType] ++;
    11511108
    1152             signDownLine[x+1] = -signDown;
    1153           }
    1154 #if SAO_SGN_FUNC
     1109            signDownLine[x+1] = -signDown;
     1110          }
    11551111          signDownLine[startX] = (Char)sgn(srcLineBelow[startX] - srcLine[startX-1]);
    1156 #else
    1157           signDownLine[startX] = (Char)m_sign[srcLineBelow[startX] - srcLine[startX-1]];
    1158 #endif
    11591112
    11601113          signTmpLine  = signUpLine;
     
    11651118          orgLine += orgStride;
    11661119        }
    1167 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    11681120        if(isCalculatePreDeblockSamples)
    11691121        {
     
    11801132              for (x=startX; x< endX; x++)
    11811133              {
    1182 #if SAO_SGN_FUNC
    11831134                edgeType = sgn(srcLine[x] - srcLineBelow[x+1]) + sgn(srcLine[x] - srcLineAbove[x-1]);
    1184 #else
    1185                 edgeType = m_sign[srcLine[x] - srcLineBelow[x+1]] + m_sign[srcLine[x] - srcLineAbove[x-1]];
    1186 #endif
    11871135                diff [edgeType] += (orgLine[x] - srcLine[x]);
    11881136                count[edgeType] ++;
     
    11931141          }
    11941142        }
    1195 #endif
    11961143      }
    11971144      break;
     
    12021149        Char *signUpLine = m_signLineBuf1+1;
    12031150
    1204 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    12051151        startX = (!isCalculatePreDeblockSamples) ? (isLeftAvail  ? 0 : 1)
    12061152                                                 : (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1))
    12071153                                                 ;
    1208 #else
    1209         startX = isLeftAvail ? 0 : 1;
    1210 #endif
    1211 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    12121154        endX   = (!isCalculatePreDeblockSamples) ? (isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1))
    12131155                                                 : (isRightAvail ? width : (width - 1))
    12141156                                                 ;
    1215 #else
    1216         endX   = isRightAvail ? (width - skipLinesR[typeIdx]) : (width - 1);
    1217 #endif
    12181157        endY   = isBelowAvail ? (height - skipLinesB[typeIdx]) : (height - 1);
    12191158
     
    12221161        for (x=startX-1; x<endX; x++)
    12231162        {
    1224 #if SAO_SGN_FUNC
    12251163          signUpLine[x] = (Char)sgn(srcLineBelow[x] - srcLine[x+1]);
    1226 #else
    1227           signUpLine[x] = (Char)m_sign[srcLineBelow[x] - srcLine[x+1]];
    1228 #endif
    12291164        }
    12301165
     
    12321167        //first line
    12331168        Pel* srcLineAbove = srcLine - srcStride;
    1234 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    12351169        firstLineStartX = (!isCalculatePreDeblockSamples) ? (isAboveAvail ? startX : endX)
    12361170                                                          : startX
     
    12391173                                                          : endX
    12401174                                                          ;
    1241 #else
    1242         firstLineStartX = isAboveAvail ? startX : endX;
    1243         firstLineEndX   = (!isRightAvail && isAboveRightAvail) ? width : endX;
    1244 #endif
    12451175        for(x=firstLineStartX; x<firstLineEndX; x++)
    12461176        {
    1247 #if SAO_SGN_FUNC
    12481177          edgeType = sgn(srcLine[x] - srcLineAbove[x+1]) - signUpLine[x-1];
    1249 #else
    1250           edgeType = m_sign[srcLine[x] - srcLineAbove[x+1]] - signUpLine[x-1];
    1251 #endif
    12521178          diff [edgeType] += (orgLine[x] - srcLine[x]);
    12531179          count[edgeType] ++;
     
    12641190          for(x=startX; x<endX; x++)
    12651191          {
    1266 #if SAO_SGN_FUNC
    12671192            signDown = (Char)sgn(srcLine[x] - srcLineBelow[x-1]);
    1268 #else
    1269             signDown = (Char)m_sign[srcLine[x] - srcLineBelow[x-1]] ;
    1270 #endif
    12711193            edgeType = signDown + signUpLine[x];
    12721194
     
    12741196            count[edgeType] ++;
    12751197
    1276             signUpLine[x-1] = -signDown;
    1277           }
    1278 #if SAO_SGN_FUNC
     1198            signUpLine[x-1] = -signDown;
     1199          }
    12791200          signUpLine[endX-1] = (Char)sgn(srcLineBelow[endX-1] - srcLine[endX]);
    1280 #else
    1281           signUpLine[endX-1] = (Char)m_sign[srcLineBelow[endX-1] - srcLine[endX]];
    1282 #endif
    12831201          srcLine  += srcStride;
    12841202          orgLine  += orgStride;
    12851203        }
    1286 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    12871204        if(isCalculatePreDeblockSamples)
    12881205        {
     
    12991216              for (x=startX; x<endX; x++)
    13001217              {
    1301 #if SAO_SGN_FUNC
    13021218                edgeType = sgn(srcLine[x] - srcLineBelow[x-1]) + sgn(srcLine[x] - srcLineAbove[x+1]);
    1303 #else
    1304                 edgeType = m_sign[srcLine[x] - srcLineBelow[x-1]] + m_sign[srcLine[x] - srcLineAbove[x+1]];
    1305 #endif
    13061219                diff [edgeType] += (orgLine[x] - srcLine[x]);
    13071220                count[edgeType] ++;
     
    13121225          }
    13131226        }
    1314 #endif
    13151227      }
    13161228      break;
    13171229    case SAO_TYPE_BO:
    13181230      {
    1319 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    13201231        startX = (!isCalculatePreDeblockSamples)?0
    13211232                                                :( isRightAvail?(width- skipLinesR[typeIdx]):width)
     
    13241235                                                :width
    13251236                                                ;
    1326 #else
    1327         endX = isRightAvail ? (width- skipLinesR[typeIdx]) : width;
    1328 #endif
    13291237        endY = isBelowAvail ? (height- skipLinesB[typeIdx]) : height;
    1330         Int shiftBits = ((compIdx == SAO_Y)?g_bitDepthY:g_bitDepthC)- NUM_SAO_BO_CLASSES_LOG2;
     1238        Int shiftBits = channelBitDepth - NUM_SAO_BO_CLASSES_LOG2;
    13311239        for (y=0; y< endY; y++)
    13321240        {
    1333 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    13341241          for (x=startX; x< endX; x++)
    1335 #else
    1336           for (x=0; x< endX; x++)
    1337 #endif
    1338           {
    1339 
    1340             Int bandIdx= srcLine[x] >> shiftBits;
     1242          {
     1243
     1244            Int bandIdx= srcLine[x] >> shiftBits;
    13411245            diff [bandIdx] += (orgLine[x] - srcLine[x]);
    13421246            count[bandIdx] ++;
     
    13451249          orgLine += orgStride;
    13461250        }
    1347 #if SAO_ENCODE_ALLOW_USE_PREDEBLOCK
    13481251        if(isCalculatePreDeblockSamples)
    13491252        {
     
    13571260              for (x=startX; x< endX; x++)
    13581261              {
    1359                 Int bandIdx= srcLine[x] >> shiftBits; 
     1262                Int bandIdx= srcLine[x] >> shiftBits;
    13601263                diff [bandIdx] += (orgLine[x] - srcLine[x]);
    13611264                count[bandIdx] ++;
     
    13681271          }
    13691272        }
    1370 #endif
    13711273      }
    13721274      break;
     
    13811283}
    13821284
     1285
    13831286//! \}
Note: See TracChangeset for help on using the changeset viewer.