Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 1547)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.cpp	(revision 1548)
@@ -1365,4 +1365,7 @@
   ("MaxNumOffsetsPerPic",                             m_maxNumOffsetsPerPic,                             2048, "Max number of SAO offset per picture (Default: 2048)")
   ("SAOLcuBoundary",                                  m_saoCtuBoundary,                                 false, "0: right/bottom CTU boundary areas skipped from SAO parameter estimation, 1: non-deblocked pixels are used for those areas")
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  ("SAOResetEncoderStateAfterIRAP",                   m_saoResetEncoderStateAfterIRAP,                  false, "When true, resets the encoder's SAO state after an IRAP (POC order). Disabled by default.")
+#endif
   ("SliceMode",                                       tmpSliceMode,                            Int(NO_SLICES), "0: Disable all Recon slice limits, 1: Enforce max # of CTUs, 2: Enforce max # of bytes, 3:specify tiles per dependent slice")
   ("SliceArgument",                                   m_sliceArgument,                                      0, "Depending on SliceMode being:"
@@ -3464,4 +3467,10 @@
     xConfirmPara( m_iIntraPeriod > 0 && m_iIntraPeriod <= m_iGOPSize ,                      "Intra period must be larger than GOP size for periodic IDR pictures");
   }
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  if (m_saoResetEncoderStateAfterIRAP)
+  {
+    xConfirmPara( m_iIntraPeriod > 0 && m_iIntraPeriod <= m_iGOPSize ,                      "Intra period must be larger than GOP size when SAOResetEncoderStateAfterIRAP is enabled");
+  }
+#endif
   xConfirmPara( m_uiMaxCUDepth < 1,                                                         "MaxPartitionDepth must be greater than zero");
   xConfirmPara( (m_uiMaxCUWidth  >> m_uiMaxCUDepth) < 4,                                    "Minimum partition width size should be larger than or equal to 8");
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 1547)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncCfg.h	(revision 1548)
@@ -322,4 +322,7 @@
   Int       m_maxNumOffsetsPerPic;                            ///< SAO maximun number of offset per picture
   Bool      m_saoCtuBoundary;                                 ///< SAO parameter estimation using non-deblocked pixels for CTU bottom and right boundary areas
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  Bool      m_saoResetEncoderStateAfterIRAP;                  ///< When true, SAO encoder state will be reset following an IRAP.
+#endif
   // coding tools (loop filter)
   Bool      m_bLoopFilterDisable;                             ///< flag for using deblocking filter
Index: /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp
===================================================================
--- /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 1547)
+++ /branches/SHM-dev/source/App/TAppEncoder/TAppEncTop.cpp	(revision 1548)
@@ -731,4 +731,7 @@
 
   m_cTEncTop.setSaoCtuBoundary                                    ( m_saoCtuBoundary);
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  m_cTEncTop.setSaoResetEncoderStateAfterIRAP                     ( m_saoResetEncoderStateAfterIRAP);
+#endif
   m_cTEncTop.setPCMInputBitDepthFlag                              ( m_bPCMInputBitDepthFlag);
   m_cTEncTop.setPCMFilterDisableFlag                              ( m_bPCMFilterDisableFlag);
Index: /branches/SHM-dev/source/Lib/TLibCommon/TComPic.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibCommon/TComPic.h	(revision 1547)
+++ /branches/SHM-dev/source/Lib/TLibCommon/TComPic.h	(revision 1548)
@@ -119,8 +119,9 @@
   Bool          getCheckLTMSBPresent     () { return m_bCheckLTMSB;}
 
-  TComPicSym*   getPicSym()           { return  &m_picSym;    }
-  const TComPicSym* getPicSym() const { return  &m_picSym;    }
-  TComSlice*    getSlice(Int i)       { return  m_picSym.getSlice(i);  }
-  Int           getPOC() const        { return  m_picSym.getSlice(m_uiCurrSliceIdx)->getPOC();  }
+  TComPicSym*   getPicSym()                        { return  &m_picSym;    }
+  const TComPicSym* getPicSym() const              { return  &m_picSym;    }
+  TComSlice*    getSlice(Int i)                    { return  m_picSym.getSlice(i);  }
+  const TComSlice* getSlice(Int i) const           { return  m_picSym.getSlice(i);  }
+  Int           getPOC() const                     { return  m_picSym.getSlice(m_uiCurrSliceIdx)->getPOC();  }
   TComDataCU*   getCtu( UInt ctuRsAddr )           { return  m_picSym.getCtu( ctuRsAddr ); }
   const TComDataCU* getCtu( UInt ctuRsAddr ) const { return  m_picSym.getCtu( ctuRsAddr ); }
Index: /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1547)
+++ /branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 1548)
@@ -172,4 +172,5 @@
 #define U0033_ALTERNATIVE_TRANSFER_CHARACTERISTICS_SEI    1 ///< Alternative transfer characteristics SEI message (JCTVC-U0033, with syntax naming from V1005)
 #define W0062_RECALCULATE_QP_TO_ALIGN_WITH_LAMBDA         0 ///< This recalculates QP to align with the derived lambda (same relation as for all intra coding is used). Currently disabled by default.
+#define OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP            1 ///< Adds command line option to reset SAO parameters after each IRAP.
 
 // ====================================================================================================================
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1547)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncCfg.h	(revision 1548)
@@ -186,4 +186,7 @@
   Int       m_maxNumOffsetsPerPic;
   Bool      m_saoCtuBoundary;
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  Bool      m_saoResetEncoderStateAfterIRAP;
+#endif
 
   //====== Motion search ========
@@ -802,4 +805,8 @@
   Void  setSaoCtuBoundary              (Bool val)                    { m_saoCtuBoundary = val; }
   Bool  getSaoCtuBoundary              ()                            { return m_saoCtuBoundary; }
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  Void  setSaoResetEncoderStateAfterIRAP(Bool b)                     { m_saoResetEncoderStateAfterIRAP = b; }
+  Bool  getSaoResetEncoderStateAfterIRAP() const                     { return m_saoResetEncoderStateAfterIRAP; }
+#endif
   Void  setLFCrossTileBoundaryFlag               ( Bool   val  )     { m_loopFilterAcrossTilesEnabledFlag = val; }
   Bool  getLFCrossTileBoundaryFlag               ()                  { return m_loopFilterAcrossTilesEnabledFlag;   }
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1547)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 1548)
@@ -2569,5 +2569,14 @@
       m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(&tempBitCounter);
       m_pcSAO->initRDOCabacCoder(m_pcEncTop->getRDGoOnSbacCoder(), pcSlice);
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+      m_pcSAO->SAOProcess(pcPic, sliceEnabled, pcPic->getSlice(0)->getLambdas(),
+                          m_pcCfg->getTestSAODisableAtPictureLevel(),
+                          m_pcCfg->getSaoEncodingRate(),
+                          m_pcCfg->getSaoEncodingRateChroma(),
+                          m_pcCfg->getSaoCtuBoundary(),
+                          m_pcCfg->getSaoResetEncoderStateAfterIRAP());
+#else
       m_pcSAO->SAOProcess(pcPic, sliceEnabled, pcPic->getSlice(0)->getLambdas(), m_pcCfg->getTestSAODisableAtPictureLevel(), m_pcCfg->getSaoEncodingRate(), m_pcCfg->getSaoEncodingRateChroma(), m_pcCfg->getSaoCtuBoundary());
+#endif
       m_pcSAO->PCMLFDisableProcess(pcPic);
       m_pcEncTop->getRDGoOnSbacCoder()->setBitstream(NULL);
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp	(revision 1547)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.cpp	(revision 1548)
@@ -120,4 +120,7 @@
 
   ::memset(m_saoDisabledRate, 0, sizeof(m_saoDisabledRate));
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  m_lastIRAPPoc = MAX_INT;
+#endif
 
   for(Int typeIdc=0; typeIdc < NUM_SAO_NEW_TYPES; typeIdc++)
@@ -239,5 +242,9 @@
 
 
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+Void TEncSampleAdaptiveOffset::SAOProcess(TComPic* pPic, Bool* sliceEnabled, const Double *lambdas, const Bool bTestSAODisableAtPictureLevel, const Double saoEncodingRate, const Double saoEncodingRateChroma, const Bool isPreDBFSamplesUsed, const Bool bResetStateAfterIRAP )
+#else
 Void TEncSampleAdaptiveOffset::SAOProcess(TComPic* pPic, Bool* sliceEnabled, const Double *lambdas, const Bool bTestSAODisableAtPictureLevel, const Double saoEncodingRate, const Double saoEncodingRateChroma, Bool isPreDBFSamplesUsed )
+#endif
 {
   TComPicYuv* orgYuv= pPic->getPicYuvOrg();
@@ -255,6 +262,11 @@
     addPreDBFStatistics(m_statData);
   }
+
   //slice on/off
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  decidePicParams(sliceEnabled, pPic, saoEncodingRate, saoEncodingRateChroma, bResetStateAfterIRAP);
+#else
   decidePicParams(sliceEnabled, pPic->getSlice(0)->getDepth(), saoEncodingRate, saoEncodingRateChroma);
+#endif
 
   //block on/off
@@ -330,6 +342,29 @@
 }
 
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+Void TEncSampleAdaptiveOffset::decidePicParams(Bool* sliceEnabled, const TComPic* pic, const Double saoEncodingRate, const Double saoEncodingRateChroma, const Bool bResetStateAfterIRAP)
+#else
 Void TEncSampleAdaptiveOffset::decidePicParams(Bool* sliceEnabled, Int picTempLayer, const Double saoEncodingRate, const Double saoEncodingRateChroma)
-{
+#endif
+{
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  if (pic->getSlice(0)->isIRAP())
+  {
+    m_lastIRAPPoc = pic->getSlice(0)->getPOC();
+  }
+  if (bResetStateAfterIRAP && pic->getSlice(0)->getPOC() > m_lastIRAPPoc)
+  { // reset
+    for (Int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
+    {
+      for (Int tempLayer = 1; tempLayer < MAX_TLAYER; tempLayer++)
+      {
+        m_saoDisabledRate[compIdx][tempLayer] = 0.0;
+      }
+    }
+    m_lastIRAPPoc = MAX_INT;
+  }
+  const Int picTempLayer = pic->getSlice(0)->getDepth();
+#endif
+
   //decide sliceEnabled[compIdx]
   const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
@@ -810,4 +845,5 @@
         {
           deriveModeNewRDO(pic->getPicSym()->getSPS().getBitDepths(), ctuRsAddr, mergeList, sliceEnabled, blkStats, modeParam, modeCost, m_pppcRDSbacCoder, SAO_CABACSTATE_BLK_CUR);
+
         }
         break;
Index: /branches/SHM-dev/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h
===================================================================
--- /branches/SHM-dev/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h	(revision 1547)
+++ /branches/SHM-dev/source/Lib/TLibEncoder/TEncSampleAdaptiveOffset.h	(revision 1548)
@@ -103,10 +103,18 @@
   Void destroyEncData();
   Void initRDOCabacCoder(TEncSbac* pcRDGoOnSbacCoder, TComSlice* pcSlice) ;
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  Void SAOProcess(TComPic* pPic, Bool* sliceEnabled, const Double *lambdas, const Bool bTestSAODisableAtPictureLevel, const Double saoEncodingRate, const Double saoEncodingRateChroma, const Bool isPreDBFSamplesUsed, const Bool bResetStateAfterIRAP);
+#else
   Void SAOProcess(TComPic* pPic, Bool* sliceEnabled, const Double *lambdas, const Bool bTestSAODisableAtPictureLevel, const Double saoEncodingRate, const Double saoEncodingRateChroma, Bool isPreDBFSamplesUsed);
+#endif
 public: //methods
   Void getPreDBFStatistics(TComPic* pPic);
 private: //methods
   Void getStatistics(SAOStatData*** blkStats, TComPicYuv* orgYuv, TComPicYuv* srcYuv,TComPic* pPic, Bool isCalculatePreDeblockSamples = false);
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  Void decidePicParams(Bool* sliceEnabled, const TComPic* pic, const Double saoEncodingRate, const Double saoEncodingRateChroma, const Bool bResetStateAfterIRAP);
+#else
   Void decidePicParams(Bool* sliceEnabled, Int picTempLayer, const Double saoEncodingRate, const Double saoEncodingRateChroma);
+#endif
   Void decideBlkParams(TComPic* pic, Bool* sliceEnabled, SAOStatData*** blkStats, TComPicYuv* srcYuv, TComPicYuv* resYuv, SAOBlkParam* reconParams, SAOBlkParam* codedParams, const Bool bTestSAODisableAtPictureLevel, const Double saoEncodingRate, const Double saoEncodingRateChroma);
   Void getBlkStats(const ComponentID compIdx, const Int channelBitDepth, SAOStatData* statsDataTypes, Pel* srcBlk, Pel* orgBlk, Int srcStride, Int orgStride, Int width, Int height, Bool isLeftAvail,  Bool isRightAvail, Bool isAboveAvail, Bool isBelowAvail, Bool isAboveLeftAvail, Bool isAboveRightAvail, Bool isCalculatePreDeblockSamples);
@@ -133,4 +141,7 @@
   SAOStatData***         m_preDBFstatData;
   Double                 m_saoDisabledRate[MAX_NUM_COMPONENT][MAX_TLAYER];
+#if OPTIONAL_RESET_SAO_ENCODING_AFTER_IRAP
+  Int                    m_lastIRAPPoc;
+#endif
   Int                    m_skipLinesR[MAX_NUM_COMPONENT][NUM_SAO_NEW_TYPES];
   Int                    m_skipLinesB[MAX_NUM_COMPONENT][NUM_SAO_NEW_TYPES];
