Index: branches/SHM-dev/source/Lib/TLibCommon/TComPic.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TComPic.cpp	(revision 879)
+++ branches/SHM-dev/source/Lib/TLibCommon/TComPic.cpp	(revision 880)
@@ -400,3 +400,34 @@
 #endif
 
+#if WPP_FIX
+UInt TComPic::getSubstreamForLCUAddr(const UInt uiLCUAddr, const Bool bAddressInRaster, TComSlice *pcSlice)
+{
+  const Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
+  UInt uiSubStrm;
+
+  if (iNumSubstreams > 1) // wavefronts, and possibly tiles being used.
+  {
+    TComPicSym &picSym=*(getPicSym());
+    const UInt uiLCUAddrRaster = bAddressInRaster?uiLCUAddr : picSym.getCUOrderMap(uiLCUAddr);
+    const UInt uiWidthInLCUs  = picSym.getFrameWidthInCU();
+    const UInt uiTileIndex=picSym.getTileIdxMap(uiLCUAddrRaster);
+    const UInt widthInTiles=(picSym.getNumColumnsMinus1()+1);
+    TComTile *pTile=picSym.getTComTile(uiTileIndex);
+    const UInt uiTileStartLCU = pTile->getFirstCUAddr();
+    const UInt uiTileLCUY = uiTileStartLCU / uiWidthInLCUs;
+    // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
+    const UInt uiLin = uiLCUAddrRaster / uiWidthInLCUs;
+          UInt uiStartingSubstreamForTile=(uiTileLCUY*widthInTiles) + (pTile->getTileHeight()*(uiTileIndex%widthInTiles));
+    uiSubStrm = uiStartingSubstreamForTile + (uiLin-uiTileLCUY);
+  }
+  else
+  {
+    // dependent tiles => substreams are "per frame".
+    uiSubStrm = 0;//uiLin % iNumSubstreams; // x modulo 1 = 0 !
+  }
+  return uiSubStrm;
+}
+#endif
+
+
 //! \}
Index: branches/SHM-dev/source/Lib/TLibCommon/TComPic.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TComPic.h	(revision 879)
+++ branches/SHM-dev/source/Lib/TLibCommon/TComPic.h	(revision 880)
@@ -223,4 +223,7 @@
   Void setCurrAuFlag(Bool x) {m_currAuFlag = x; }
 #endif
+#if WPP_FIX
+  UInt          getSubstreamForLCUAddr(const UInt uiLCUAddr, const Bool bAddressInRaster, TComSlice *pcSlice);
+#endif
 };// END CLASS DEFINITION TComPic
 
Index: branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 879)
+++ branches/SHM-dev/source/Lib/TLibCommon/TypeDef.h	(revision 880)
@@ -274,4 +274,6 @@
   AUX_ID            = 3,
 };
+
+#define WPP_FIX                          1
 
 /// normative encoder constraints --------
Index: branches/SHM-dev/source/Lib/TLibDecoder/TDecSlice.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibDecoder/TDecSlice.cpp	(revision 879)
+++ branches/SHM-dev/source/Lib/TLibDecoder/TDecSlice.cpp	(revision 880)
@@ -146,5 +146,7 @@
   UInt uiTilesAcross   = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
   TComSlice*  pcSlice = rpcPic->getSlice(rpcPic->getCurrSliceIdx());
+#if !WPP_FIX
   Int  iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
+#endif
 
   // delete decoders if already allocated in previous slice
@@ -193,4 +195,17 @@
   UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
   //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
+
+#if WPP_FIX
+  UInt uiTileCol;
+  UInt uiTileLCUX;
+  const Bool depSliceSegmentsEnabled = rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getPPS()->getDependentSliceSegmentsEnabledFlag();
+  const UInt startTileIdx=rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr);
+  TComTile *pCurrentTile=rpcPic->getPicSym()->getTComTile(startTileIdx);
+  UInt uiTileStartLCU = pCurrentTile->getFirstCUAddr(); // Code tidy
+
+  // The first LCU of the slice is the first coded substream, but the global substream number, as calculated by getSubstreamForLCUAddr may be higher.
+  // This calculates the common offset for all substreams in this slice.
+  const UInt subStreamOffset=rpcPic->getSubstreamForLCUAddr(iStartCUAddr, true, pcSlice);
+#else
   UInt uiCol=0, uiLin=0, uiSubStrm=0;
 
@@ -201,13 +216,28 @@
   Bool depSliceSegmentsEnabled = rpcPic->getSlice(rpcPic->getCurrSliceIdx())->getPPS()->getDependentSliceSegmentsEnabledFlag();
   uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr))->getFirstCUAddr();
+#endif
   if( depSliceSegmentsEnabled )
   {
+#if WPP_FIX
+    if( (!rpcPic->getSlice(rpcPic->getCurrSliceIdx())->isNextSlice()) && iStartCUAddr != uiTileStartLCU)  // Code tidy // Is this a dependent slice segment and not the start of a tile?
+#else
     if( (!rpcPic->getSlice(rpcPic->getCurrSliceIdx())->isNextSlice()) &&
        iStartCUAddr != rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr))->getFirstCUAddr())
+#endif
     {
       if(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
       {
+#if WPP_FIX
+        uiTileCol = startTileIdx % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // Code tidy
+#else
         uiTileCol = rpcPic->getPicSym()->getTileIdxMap(iStartCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
+#endif
         m_pcBufferSbacDecoders[uiTileCol].loadContexts( CTXMem[1]  );//2.LCU
+#if WPP_FIX
+        if ( pCurrentTile->getTileWidth() < 2)
+        {
+          CTXMem[0]->loadContexts(pcSbacDecoder); // If tile width is less than 2, need to ensure CTX states get initialised to un-adapted CABAC. Set here, to load a few lines later (!)
+        }
+#else
         if ( (iStartCUAddr%uiWidthInLCUs+1) >= uiWidthInLCUs  )
         {
@@ -219,7 +249,12 @@
           }
         }
+#endif
       }
       pcSbacDecoder->loadContexts(CTXMem[0] ); //end of depSlice-1
+#if WPP_FIX
+      pcSbacDecoders[0].loadContexts(pcSbacDecoder); // The first substream used for the slice will always be 0. (The original code was equivalent)
+#else
       pcSbacDecoders[uiSubStrm].loadContexts(pcSbacDecoder);
+#endif
     }
     else
@@ -239,14 +274,21 @@
     uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr();
     uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
+#if WPP_FIX
+    UInt uiCol     = iCUAddr % uiWidthInLCUs;
+    UInt uiSubStrm=rpcPic->getSubstreamForLCUAddr(iCUAddr, true, pcSlice)-subStreamOffset;
+#else
     uiCol     = iCUAddr % uiWidthInLCUs;
     // The 'line' is now relative to the 1st line in the slice, not the 1st line in the picture.
     uiLin     = (iCUAddr/uiWidthInLCUs)-(iStartCUAddr/uiWidthInLCUs);
+#endif
     // inherit from TR if necessary, select substream to use.
     if( (pcSlice->getPPS()->getNumSubstreams() > 1) || ( depSliceSegmentsEnabled  && (uiCol == uiTileLCUX)&&(pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) ))
     {
+#if !WPP_FIX
       // independent tiles => substreams are "per tile".  iNumSubstreams has already been multiplied.
       iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
       uiSubStrm = rpcPic->getPicSym()->getTileIdxMap(iCUAddr)*iNumSubstreamsPerTile
                   + uiLin%iNumSubstreamsPerTile;
+#endif
       m_pcEntropyDecoder->setBitstream( ppcSubstreams[uiSubStrm] );
       // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
@@ -280,4 +322,5 @@
       pcSbacDecoder->load(&pcSbacDecoders[uiSubStrm]);  //this load is used to simplify the code (avoid to change all the call to pcSbacDecoders)
     }
+#if !WPP_FIX
     else if ( pcSlice->getPPS()->getNumSubstreams() <= 1 )
     {
@@ -285,4 +328,5 @@
       iNumSubstreamsPerTile = 1;
     }
+#endif
 
     if ( (iCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(iCUAddr))->getFirstCUAddr()) && // 1st in tile.
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncCavlc.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 879)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncCavlc.cpp	(revision 880)
@@ -2427,5 +2427,7 @@
   }
   UInt numEntryPointOffsets = 0, offsetLenMinus1 = 0, maxOffset = 0;
+#if !WPP_FIX
   Int  numZeroSubstreamsAtStartOfSlice  = 0;
+#endif
   UInt *entryPointOffset = NULL;
   if ( pSlice->getPPS()->getTilesEnabledFlag() )
@@ -2454,7 +2456,13 @@
     UInt* pSubstreamSizes               = pSlice->getSubstreamSizes();
     Int maxNumParts                       = pSlice->getPic()->getNumPartInCU();
+#if WPP_FIX
+    Int  numZeroSubstreamsAtStartOfSlice  = pSlice->getPic()->getSubstreamForLCUAddr(pSlice->getSliceSegmentCurStartCUAddr()/maxNumParts, false, pSlice); 
+    Int  subStreamOfLastSegmentOfSlice    = pSlice->getPic()->getSubstreamForLCUAddr((pSlice->getSliceSegmentCurEndCUAddr()/maxNumParts)-1, false, pSlice); 
+    numEntryPointOffsets                  = subStreamOfLastSegmentOfSlice-numZeroSubstreamsAtStartOfSlice;
+#else
     numZeroSubstreamsAtStartOfSlice       = pSlice->getSliceSegmentCurStartCUAddr()/maxNumParts/pSlice->getPic()->getFrameWidthInCU();
     Int  numZeroSubstreamsAtEndOfSlice    = pSlice->getPic()->getFrameHeightInCU()-1 - ((pSlice->getSliceSegmentCurEndCUAddr()-1)/maxNumParts/pSlice->getPic()->getFrameWidthInCU());
     numEntryPointOffsets                  = pSlice->getPPS()->getNumSubstreams() - numZeroSubstreamsAtStartOfSlice - numZeroSubstreamsAtEndOfSlice - 1;
+#endif
     pSlice->setNumEntryPointOffsets(numEntryPointOffsets);
     entryPointOffset           = new UInt[numEntryPointOffsets];
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 879)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncGOP.cpp	(revision 880)
@@ -2086,5 +2086,9 @@
 
     // Allocate some coders, now we know how many tiles there are.
+#if WPP_FIX
+    const Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
+#else
     Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
+#endif
 
     //generate the Coding Order Map and Inverse Coding Order Map
@@ -2799,5 +2803,9 @@
             m_pcEntropyCoder->setEntropyCoder ( m_pcSbacCoder, pcSlice );
             m_pcEntropyCoder->resetEntropy    ();
+#if WPP_FIX
+            for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ ) 
+#else
             for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
+#endif
             {
               m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
@@ -2811,5 +2819,9 @@
             m_pcSbacCoder->init( (TEncBinIf*)m_pcBinCABAC );
             {
+#if WPP_FIX
+              for ( UInt ui = 0 ; ui < iNumSubstreams ; ui++ )
+#else
               for ( UInt ui = 0 ; ui < pcSlice->getPPS()->getNumSubstreams() ; ui++ )
+#endif
               {
                 m_pcEntropyCoder->setEntropyCoder ( &pcSbacCoders[ui], pcSlice );
@@ -2838,5 +2850,5 @@
 
           pcSlice->setTileOffstForMultES( uiOneBitstreamPerSliceLength );
-            pcSlice->setTileLocationCount ( 0 );
+          pcSlice->setTileLocationCount ( 0 );
           m_pcSliceEncoder->encodeSlice(pcPic, pcSubstreamsOut);
 
@@ -2865,12 +2877,23 @@
 
               Bool bNextSubstreamInNewTile = ((ui+1) < iNumSubstreams)&& ((ui+1)%uiNumSubstreamsPerTile == 0);
+#if WPP_FIX
+              if (bNextSubstreamInNewTile &&  !pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag() ) 
+#else
               if (bNextSubstreamInNewTile)
+#endif
               {
                 pcSlice->setTileLocation(ui/uiNumSubstreamsPerTile, pcSlice->getTileOffstForMultES()+(uiTotalCodedSize>>3));
               }
+#if WPP_FIX
+              if (ui+1 < iNumSubstreams)
+              {
+                puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits() + (pcSubstreamsOut[ui].countStartCodeEmulations()<<3);
+              }
+#else
               if (ui+1 < pcSlice->getPPS()->getNumSubstreams())
               {
                 puiSubstreamSizes[ui] = pcSubstreamsOut[ui].getNumberOfWrittenBits() + (pcSubstreamsOut[ui].countStartCodeEmulations()<<3);
               }
+#endif
             }
 
@@ -2889,5 +2912,20 @@
             // Substreams...
             TComOutputBitstream *pcOut = pcBitstreamRedirect;
-          Int offs = 0;
+#if WPP_FIX 
+            Int numZeroSubstreamsAtStartOfSlice = 0; 
+            Int numSubstreamsToCode = pcSlice->getPPS()->getNumSubstreams(); 
+            if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag()) 
+            { 
+              Int  maxNumParts                      = pcPic->getNumPartInCU(); 
+              numZeroSubstreamsAtStartOfSlice  = pcPic->getSubstreamForLCUAddr(pcSlice->getSliceSegmentCurStartCUAddr()/maxNumParts, false, pcSlice); 
+              // 1st line present for WPP. 
+              numSubstreamsToCode  = pcSlice->getNumEntryPointOffsets()+1; 
+            } 
+            for ( UInt ui = 0 ; ui < numSubstreamsToCode; ui++ ) 
+            { 
+              pcOut->addSubstream(&pcSubstreamsOut[ui+numZeroSubstreamsAtStartOfSlice]); 
+            } 
+#else 
+            Int offs = 0;
           Int nss = pcSlice->getPPS()->getNumSubstreams();
           if (pcSlice->getPPS()->getEntropyCodingSyncEnabledFlag())
@@ -2901,4 +2939,5 @@
             pcOut->addSubstream(&pcSubstreamsOut[ui+offs]);
             }
+#endif
           }
 
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.cpp
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 879)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.cpp	(revision 880)
@@ -836,5 +836,7 @@
 Void TEncSlice::compressSlice( TComPic*& rpcPic )
 {
+#if !WPP_FIX
   UInt  uiCUAddr;
+#endif
   UInt   uiStartCUAddr;
   UInt   uiBoundingCUAddr;
@@ -907,4 +909,8 @@
   TEncSbac**** ppppcRDSbacCoders    = pcEncTop->getRDSbacCoders();
   TComBitCounter* pcBitCounters     = pcEncTop->getBitCounters();
+#if WPP_FIX
+  const Int  iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
+  const UInt uiTilesAcross  = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
+#else
   Int  iNumSubstreams = 1;
   UInt uiTilesAcross  = 0;
@@ -912,4 +918,5 @@
   iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
   uiTilesAcross = rpcPic->getPicSym()->getNumColumnsMinus1()+1;
+#endif
   delete[] m_pcBufferSbacCoders;
   delete[] m_pcBufferBinCoderCABACs;
@@ -943,4 +950,12 @@
   UInt uiWidthInLCUs  = rpcPic->getPicSym()->getFrameWidthInCU();
   //UInt uiHeightInLCUs = rpcPic->getPicSym()->getFrameHeightInCU();
+#if WPP_FIX
+  UInt      uiTileCol               = 0; 
+  Bool      depSliceSegmentsEnabled = pcSlice->getPPS()->getDependentSliceSegmentsEnabledFlag(); 
+  UInt      uiCUAddr                = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
+  UInt      currentTileIdx          = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr); 
+  TComTile *pCurrentTile            = rpcPic->getPicSym()->getTComTile(currentTileIdx); 
+  UInt      uiTileStartLCU          = pCurrentTile->getFirstCUAddr();
+#else
   UInt uiCol=0, uiLin=0, uiSubStrm=0;
   UInt uiTileCol      = 0;
@@ -950,10 +965,24 @@
   uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU());
   uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
+#endif
   if( depSliceSegmentsEnabled )
   {
     if((pcSlice->getSliceSegmentCurStartCUAddr()!= pcSlice->getSliceCurStartCUAddr())&&(uiCUAddr != uiTileStartLCU))
     {
+#if WPP_FIX
+      UInt uiSubStrm=0;
+#endif
       if( m_pcCfg->getWaveFrontsynchro() )
       {
+#if WPP_FIX
+        uiTileCol = currentTileIdx % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); 
+         m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] ); 
+         //uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
+         uiSubStrm=rpcPic->getSubstreamForLCUAddr(uiCUAddr, true, pcSlice); 
+         if ( pCurrentTile->getTileWidth() < 2) 
+         { 
+           CTXMem[0]->loadContexts(m_pcSbacCoder); 
+         } 
+#else
         uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
         m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
@@ -972,4 +1001,5 @@
           }
         }
+#endif
       }
       m_pppcRDSbacCoder[0][CI_CURR_BEST]->loadContexts( CTXMem[0] );
@@ -998,4 +1028,12 @@
     uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1); // what column of tiles are we in?
     uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
+#if WPP_FIX
+    UInt uiTileLCUX = uiTileStartLCU % uiWidthInLCUs; 
+    //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr(); 
+    UInt uiCol     = uiCUAddr % uiWidthInLCUs; 
+    UInt uiSubStrm=rpcPic->getSubstreamForLCUAddr(uiCUAddr, true, pcSlice); 
+
+    if ( ((iNumSubstreams > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
+#else 
     uiTileLCUX = uiTileStartLCU % uiWidthInLCUs;
     //UInt uiSliceStartLCU = pcSlice->getSliceCurStartCUAddr();
@@ -1015,4 +1053,5 @@
     }
     if ( ((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled ) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
+#endif
     {
       // We'll sync if the TR is available.
@@ -1138,5 +1177,9 @@
     ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]->load( m_pppcRDSbacCoder[0][CI_CURR_BEST] );
     //Store probabilties of second LCU in line into buffer
+#if WPP_FIX
+    if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (iNumSubstreams > 1)) && m_pcCfg->getWaveFrontsynchro()) 
+#else
     if ( ( uiCol == uiTileLCUX+1) && (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && m_pcCfg->getWaveFrontsynchro())
+#endif
     {
       m_pcBufferSbacCoders[uiTileCol].loadContexts(ppppcRDSbacCoders[uiSubStrm][0][CI_CURR_BEST]);
@@ -1177,5 +1220,9 @@
     m_uiPicDist      += pcCU->getTotalDistortion();
   }
+#if WPP_FIX
+  if ((iNumSubstreams > 1) && !depSliceSegmentsEnabled)
+#else
   if ((pcSlice->getPPS()->getNumSubstreams() > 1) && !depSliceSegmentsEnabled)
+#endif
   {
     pcSlice->setNextSlice( true );
@@ -1239,5 +1286,9 @@
   TEncTop* pcEncTop = (TEncTop*) m_pcCfg;
   TEncSbac* pcSbacCoders = pcEncTop->getSbacCoders(); //coder for each substream
+#if WPP_FIX
+  const Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams(); 
+#else
   Int iNumSubstreams = pcSlice->getPPS()->getNumSubstreams();
+#endif
   UInt uiBitsOriginallyInSubstreams = 0;
   {
@@ -1268,9 +1319,19 @@
                                                                                                an encoding order index, so we need to convert the index (uiStartCUAddr)
                                                                                                into the real raster scan address (uiCUAddr) via the CUOrderMap */
+#if WPP_FIX
+  UInt currentTileIdx=rpcPic->getPicSym()->getTileIdxMap(uiCUAddr); 
+  TComTile *pCurrentTile=rpcPic->getPicSym()->getTComTile(currentTileIdx); 
+  uiTileStartLCU = pCurrentTile->getFirstCUAddr(); 
+#else
   uiTileStartLCU = rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr();
+#endif
   if( depSliceSegmentsEnabled )
   {
+#if WPP_FIX
+    if( pcSlice->isNextSlice()|| uiCUAddr == uiTileStartLCU)
+#else
     if( pcSlice->isNextSlice()||
         uiCUAddr == rpcPic->getPicSym()->getTComTile(rpcPic->getPicSym()->getTileIdxMap(uiCUAddr))->getFirstCUAddr())
+#endif
     {
       if(m_pcCfg->getWaveFrontsynchro())
@@ -1284,6 +1345,18 @@
       if(m_pcCfg->getWaveFrontsynchro())
       {
+#if WPP_FIX
+        uiTileCol = currentTileIdx % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
+#else
         uiTileCol = rpcPic->getPicSym()->getTileIdxMap(uiCUAddr) % (rpcPic->getPicSym()->getNumColumnsMinus1()+1);
+#endif
         m_pcBufferSbacCoders[uiTileCol].loadContexts( CTXMem[1] );
+#if WPP_FIX
+        uiCUAddr = rpcPic->getPicSym()->getCUOrderMap( uiStartCUAddr /rpcPic->getNumPartInCU()); 
+        uiSubStrm=rpcPic->getSubstreamForLCUAddr(uiCUAddr, true, pcSlice); 
+        if ( pCurrentTile->getTileWidth() < 2) 
+        { 
+          CTXMem[0]->loadContexts(m_pcSbacCoder); 
+        } 
+#else
         Int iNumSubstreamsPerTile = iNumSubstreams/rpcPic->getPicSym()->getNumTiles();
         uiLin     = uiCUAddr / uiWidthInLCUs;
@@ -1299,4 +1372,5 @@
           }
         }
+#endif
       }
       pcSbacCoders[uiSubStrm].loadContexts( CTXMem[0] );
@@ -1315,4 +1389,7 @@
     uiCol     = uiCUAddr % uiWidthInLCUs;
     uiLin     = uiCUAddr / uiWidthInLCUs;
+#if WPP_FIX
+    uiSubStrm=rpcPic->getSubstreamForLCUAddr(uiCUAddr, true, pcSlice);
+#else
     if (pcSlice->getPPS()->getNumSubstreams() > 1)
     {
@@ -1327,8 +1404,13 @@
       uiSubStrm = uiLin % iNumSubstreams;
     }
+#endif
 
     m_pcEntropyCoder->setBitstream( &pcSubstreams[uiSubStrm] );
     // Synchronize cabac probabilities with upper-right LCU if it's available and we're at the start of a line.
+#if WPP_FIX
+    if (((iNumSubstreams > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
+#else
     if (((pcSlice->getPPS()->getNumSubstreams() > 1) || depSliceSegmentsEnabled) && (uiCol == uiTileLCUX) && m_pcCfg->getWaveFrontsynchro())
+#endif
     {
       // We'll sync if the TR is available.
@@ -1368,4 +1450,7 @@
         // When tiles are independent, we have "substreams per tile".  Each substream has already been terminated, and we no longer
         // have to perform it here.
+#if WPP_FIX
+        if (iNumSubstreams <= 1)
+#else
         if (pcSlice->getPPS()->getNumSubstreams() > 1)
         {
@@ -1373,4 +1458,5 @@
         }
         else
+#endif
         {
           SliceType sliceType  = pcSlice->getSliceType();
@@ -1448,5 +1534,9 @@
     pcSbacCoders[uiSubStrm].load(m_pcSbacCoder);   //load back status of the entropy coder after encoding the LCU into relevant bitstream entropy coder
     //Store probabilties of second LCU in line into buffer
+#if WPP_FIX
+    if ( (depSliceSegmentsEnabled || (iNumSubstreams > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
+#else
     if ( (depSliceSegmentsEnabled || (pcSlice->getPPS()->getNumSubstreams() > 1)) && (uiCol == uiTileLCUX+1) && m_pcCfg->getWaveFrontsynchro())
+#endif
     {
       m_pcBufferSbacCoders[uiTileCol].loadContexts( &pcSbacCoders[uiSubStrm] );
@@ -1480,4 +1570,186 @@
 }
 
+#if WPP_FIX 
+Void TEncSlice::calculateBoundingCUAddrForSlice(UInt &uiStartCUAddrSlice, UInt &uiBoundingCUAddrSlice, Bool &bReachedTileBoundary, TComPic*& rpcPic, Bool bEncodeSlice, Int sliceMode, Int sliceArgument, UInt uiSliceCurEndCUAddr) 
+{ 
+  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx()); 
+  UInt uiNumberOfCUsInFrame = rpcPic->getNumCUsInFrame(); 
+  const UInt scaleCUAddr = rpcPic->getNumPartInCU(); // due to fine granularity slices all addresses are scaled. 
+  uiBoundingCUAddrSlice=0; 
+  bReachedTileBoundary=false; 
+
+  switch (sliceMode) 
+  { 
+  case FIXED_NUMBER_OF_LCU: 
+    { 
+      UInt uiCUAddrIncrement    = sliceArgument; 
+      uiBoundingCUAddrSlice     = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*scaleCUAddr) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*scaleCUAddr; 
+    } 
+    break; 
+  case FIXED_NUMBER_OF_BYTES: 
+    if (bEncodeSlice) 
+      uiBoundingCUAddrSlice     = uiSliceCurEndCUAddr; 
+    else 
+      uiBoundingCUAddrSlice     = uiNumberOfCUsInFrame*scaleCUAddr; 
+    break; 
+  case FIXED_NUMBER_OF_TILES: 
+    { 
+      UInt tileIdx              = rpcPic->getPicSym()->getTileIdxMap( rpcPic->getPicSym()->getCUOrderMap(uiStartCUAddrSlice/scaleCUAddr) ); 
+      UInt uiCUAddrIncrement    = 0; 
+      UInt tileTotalCount       = (rpcPic->getPicSym()->getNumColumnsMinus1()+1) * (rpcPic->getPicSym()->getNumRowsMinus1()+1); 
+
+      for(UInt tileIdxIncrement = 0; tileIdxIncrement < sliceArgument; tileIdxIncrement++) 
+      { 
+        if((tileIdx + tileIdxIncrement) < tileTotalCount) 
+        { 
+          UInt tileWidthInLcu   = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileWidth(); 
+          UInt tileHeightInLcu  = rpcPic->getPicSym()->getTComTile(tileIdx + tileIdxIncrement)->getTileHeight(); 
+          uiCUAddrIncrement    += (tileWidthInLcu * tileHeightInLcu * scaleCUAddr); 
+        } 
+      } 
+
+      uiBoundingCUAddrSlice     = ((uiStartCUAddrSlice + uiCUAddrIncrement) < uiNumberOfCUsInFrame*scaleCUAddr) ? (uiStartCUAddrSlice + uiCUAddrIncrement) : uiNumberOfCUsInFrame*scaleCUAddr; 
+    } 
+    break; 
+  default: 
+    uiBoundingCUAddrSlice       = uiNumberOfCUsInFrame*scaleCUAddr; 
+    break; 
+  } 
+
+  // Adjust for tiles and wavefronts. 
+  if ((sliceMode == FIXED_NUMBER_OF_LCU || sliceMode == FIXED_NUMBER_OF_BYTES) && 
+    (m_pcCfg->getNumRowsMinus1() > 0 || m_pcCfg->getNumColumnsMinus1() > 0)) 
+  { 
+    const UInt lcuEncAddrStart = (uiStartCUAddrSlice+scaleCUAddr-1)/scaleCUAddr; 
+    const UInt lcuAddr = rpcPic->getPicSym()->getCUOrderMap(lcuEncAddrStart); 
+    const UInt startTileIdx = rpcPic->getPicSym()->getTileIdxMap(lcuAddr); 
+    const Bool bWavefrontsEnabled = m_pcCfg->getWaveFrontsynchro(); 
+
+    TComTile *pStartingTile = rpcPic->getPicSym()->getTComTile(startTileIdx); 
+    const UInt uiTileStartLCUEncAddr      = rpcPic->getPicSym()->getInverseCUOrderMap(pStartingTile->getFirstCUAddr()); 
+    const UInt uiTileStartWidth           = pStartingTile->getTileWidth(); 
+    const UInt uiTileStartHeight          = pStartingTile->getTileHeight(); 
+    const UInt uiTileLastLCUEncAddr_excl  = uiTileStartLCUEncAddr + uiTileStartWidth*uiTileStartHeight; 
+    const UInt tileBoundingCUAddrSlice    = uiTileLastLCUEncAddr_excl * scaleCUAddr; 
+
+    const UInt lcuColumnOfStartingTile=((lcuEncAddrStart-uiTileStartLCUEncAddr)%uiTileStartWidth); 
+    if (bWavefrontsEnabled && lcuColumnOfStartingTile!=0) 
+    { 
+      // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row 
+      const UInt numberOfLCUsToEndOfRow=uiTileStartWidth-lcuColumnOfStartingTile; 
+      const UInt wavefrontTileBoundingCUAddrSlice = (lcuEncAddrStart+numberOfLCUsToEndOfRow)*scaleCUAddr; 
+      if (wavefrontTileBoundingCUAddrSlice < uiBoundingCUAddrSlice) 
+      { 
+        uiBoundingCUAddrSlice = wavefrontTileBoundingCUAddrSlice; 
+      } 
+    } 
+
+    if (tileBoundingCUAddrSlice < uiBoundingCUAddrSlice) 
+    { 
+      uiBoundingCUAddrSlice = tileBoundingCUAddrSlice; 
+      bReachedTileBoundary = true; 
+    } 
+  } 
+  else if (pcSlice->getPPS()->getNumSubstreams() > 1 && (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*scaleCUAddr) != 0)) 
+  { 
+    // WPP: if a slice does not start at the beginning of a CTB row, it must end within the same CTB row 
+    uiBoundingCUAddrSlice = min(uiBoundingCUAddrSlice, uiStartCUAddrSlice - (uiStartCUAddrSlice % (rpcPic->getFrameWidthInCU()*scaleCUAddr)) + (rpcPic->getFrameWidthInCU()*scaleCUAddr)); 
+  } 
+
+  //calculate real slice start address (fine granularity slices) 
+  { 
+    UInt uiInternalAddress = rpcPic->getPicSym()->getPicSCUAddr(uiStartCUAddrSlice) % scaleCUAddr; 
+    UInt uiExternalAddress = rpcPic->getPicSym()->getPicSCUAddr(uiStartCUAddrSlice) / scaleCUAddr; 
+    UInt uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; 
+    UInt uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; 
+#if REPN_FORMAT_IN_VPS
+    UInt uiWidth = pcSlice->getPicWidthInLumaSamples();
+    UInt uiHeight = pcSlice->getPicHeightInLumaSamples();
+#else
+    UInt uiWidth = pcSlice->getSPS()->getPicWidthInLumaSamples(); 
+    UInt uiHeight = pcSlice->getSPS()->getPicHeightInLumaSamples(); 
+#endif
+    while((uiPosX>=uiWidth||uiPosY>=uiHeight)&&!(uiPosX>=uiWidth&&uiPosY>=uiHeight)) 
+    { 
+      uiInternalAddress++; 
+      if(uiInternalAddress>=scaleCUAddr) 
+      { 
+        uiInternalAddress=0; 
+        uiExternalAddress = rpcPic->getPicSym()->getCUOrderMap(rpcPic->getPicSym()->getInverseCUOrderMap(uiExternalAddress)+1); 
+      } 
+      uiPosX = ( uiExternalAddress % rpcPic->getFrameWidthInCU() ) * g_uiMaxCUWidth+ g_auiRasterToPelX[ g_auiZscanToRaster[uiInternalAddress] ]; 
+      uiPosY = ( uiExternalAddress / rpcPic->getFrameWidthInCU() ) * g_uiMaxCUHeight+ g_auiRasterToPelY[ g_auiZscanToRaster[uiInternalAddress] ]; 
+    } 
+    UInt uiRealStartAddress = rpcPic->getPicSym()->getPicSCUEncOrder(uiExternalAddress*scaleCUAddr+uiInternalAddress); 
+
+    uiStartCUAddrSlice=uiRealStartAddress; 
+  } 
+} 
+
+/** Determines the starting and bounding LCU address of current slice / dependent slice 
+* \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true] 
+* \returns Updates uiStartCUAddr, uiBoundingCUAddr with appropriate LCU address 
+*/ 
+Void TEncSlice::xDetermineStartAndBoundingCUAddr  ( UInt& startCUAddr, UInt& boundingCUAddr, TComPic*& rpcPic, Bool bEncodeSlice ) 
+{ 
+  TComSlice* pcSlice = rpcPic->getSlice(getSliceIdx()); 
+
+  // Non-dependent slice 
+  UInt uiStartCUAddrSlice   = pcSlice->getSliceCurStartCUAddr(); 
+  Bool bTileBoundarySlice   = false; 
+  UInt uiBoundingCUAddrSlice; 
+  calculateBoundingCUAddrForSlice(uiStartCUAddrSlice, uiBoundingCUAddrSlice, bTileBoundarySlice, rpcPic, bEncodeSlice, m_pcCfg->getSliceMode(), m_pcCfg->getSliceArgument(), pcSlice->getSliceCurEndCUAddr()); 
+  pcSlice->setSliceCurEndCUAddr( uiBoundingCUAddrSlice ); 
+  pcSlice->setSliceCurStartCUAddr(uiStartCUAddrSlice); 
+
+  // Dependent slice 
+  UInt startCUAddrSliceSegment    = pcSlice->getSliceSegmentCurStartCUAddr(); 
+  Bool bTileBoundarySliceSegment  = false; 
+  UInt boundingCUAddrSliceSegment; 
+  calculateBoundingCUAddrForSlice(startCUAddrSliceSegment, boundingCUAddrSliceSegment, bTileBoundarySliceSegment, rpcPic, bEncodeSlice, m_pcCfg->getSliceSegmentMode(), m_pcCfg->getSliceSegmentArgument(), pcSlice->getSliceSegmentCurEndCUAddr()); 
+  pcSlice->setSliceSegmentCurEndCUAddr( boundingCUAddrSliceSegment ); 
+  pcSlice->setSliceSegmentCurStartCUAddr(startCUAddrSliceSegment); 
+
+  // Make a joint decision based on reconstruction and dependent slice bounds 
+  startCUAddr    = max(uiStartCUAddrSlice   , startCUAddrSliceSegment   ); 
+  boundingCUAddr = min(uiBoundingCUAddrSlice, boundingCUAddrSliceSegment); 
+
+
+  if (!bEncodeSlice) 
+  { 
+    // For fixed number of LCU within an entropy and reconstruction slice we already know whether we will encounter end of entropy and/or reconstruction slice 
+    // first. Set the flags accordingly. 
+    if ( (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU) 
+      || (m_pcCfg->getSliceMode()==0 && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU) 
+      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_LCU && m_pcCfg->getSliceSegmentMode()==0) 
+      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_LCU) 
+      || (m_pcCfg->getSliceMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceSegmentMode()==0) 
+      || (m_pcCfg->getSliceSegmentMode()==FIXED_NUMBER_OF_TILES && m_pcCfg->getSliceMode()==0) 
+      || bTileBoundarySlice || bTileBoundarySliceSegment ) 
+    { 
+      if (uiBoundingCUAddrSlice < boundingCUAddrSliceSegment) 
+      { 
+        pcSlice->setNextSlice       ( true ); 
+        pcSlice->setNextSliceSegment( false ); 
+      } 
+      else if (uiBoundingCUAddrSlice > boundingCUAddrSliceSegment) 
+      { 
+        pcSlice->setNextSlice       ( false ); 
+        pcSlice->setNextSliceSegment( true ); 
+      } 
+      else 
+      { 
+        pcSlice->setNextSlice       ( true ); 
+        pcSlice->setNextSliceSegment( true ); 
+      } 
+    } 
+    else 
+    { 
+      pcSlice->setNextSlice       ( false ); 
+      pcSlice->setNextSliceSegment( false ); 
+    } 
+  } 
+} 
+#else 
 /** Determines the starting and bounding LCU address of current slice / dependent slice
  * \param bEncodeSlice Identifies if the calling function is compressSlice() [false] or encodeSlice() [true]
@@ -1816,4 +2088,5 @@
   }
 }
+#endif
 
 Double TEncSlice::xGetQPValueAccordingToLambda ( Double lambda )
Index: branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.h
===================================================================
--- branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.h	(revision 879)
+++ branches/SHM-dev/source/Lib/TLibEncoder/TEncSlice.h	(revision 880)
@@ -150,4 +150,8 @@
   Void      setCtxMem( TEncSbac* sb, Int b )   { CTXMem[b] = sb; }
 
+#if WPP_FIX 
+  Void     calculateBoundingCUAddrForSlice(UInt &uiStartCUAddrSlice, UInt &uiBoundingCUAddrSlice, Bool &bReachedTileBoundary, TComPic*& rpcPic, Bool bEncodeSlice, Int sliceMode, Int sliceArgument, UInt uiSliceCurEndCUAddr); 
+#endif
+
 private:
   Double  xGetQPValueAccordingToLambda ( Double lambda );
