shithub: openh264

Download patch

ref: 7f172770a255fdabb142ace0ebab099bb3a19efa
parent: a4caef0fa3b700927b005d6d31706476ada84a55
parent: 71750df1cc651fc435e7e19aed6f9cf111e9d76e
author: sijchen <[email protected]>
date: Wed Mar 29 10:17:20 EDT 2017

Merge pull request #2705 from shihuade/MultiThread_V10.5_#1711#1715_#1721

Slice buffer reallocate design::PR05::refactoring for slice rc/boundary module etc

--- a/codec/encoder/core/inc/rc.h
+++ b/codec/encoder/core/inc/rc.h
@@ -168,6 +168,7 @@
 
 // bits allocation and status
 int32_t   iRemainingBits;
+int32_t   iBitsPerMb;
 int32_t   iTargetBits;
 int32_t   iCurrentBitsLevel;//0:normal; 1:limited; 2:exceeded.
 
@@ -191,7 +192,6 @@
 int32_t   iMaxFrameQp;
 int32_t   iNumberMbFrame;
 int32_t   iNumberMbGom;
-int32_t   iSliceNum;
 int32_t   iGomSize;
 
 int32_t   iSkipFrameNum;
@@ -261,6 +261,7 @@
 PWelsRCPostFrameSkippingFunc    pfWelsRcPostFrameSkipping;
 } SWelsRcFunc;
 
+void RCInitOneSliceInformation(sWelsEncCtx* pEncCtx, SSlice* pSlice);
 void CheckFrameSkipBasedMaxbr (sWelsEncCtx* pCtx,const long long uiTimeStamp, int32_t iDidIdx);
 void UpdateBufferWhenFrameSkipped(sWelsEncCtx* pCtx, int32_t iSpatialNum);
 void UpdateMaxBrCheckWindowStatus(sWelsEncCtx* pCtx, int32_t iSpatialNum, const long long uiTimeStamp);
--- a/codec/encoder/core/inc/slice.h
+++ b/codec/encoder/core/inc/slice.h
@@ -185,6 +185,7 @@
 uint8_t         sScaleShift;
 
 uint32_t        uiSliceIdx;
+uint32_t        uiThreadIdx;
 bool            bSliceHeaderExtFlag; // Indicate which slice header is used, avc or ext?
 uint8_t         uiLastMbQp;             // stored qp for last mb coded, maybe more efficient for mb skip detection etc.
 
--- a/codec/encoder/core/inc/svc_enc_slice_segment.h
+++ b/codec/encoder/core/inc/svc_enc_slice_segment.h
@@ -149,12 +149,12 @@
 /*!
  * \brief   Get first mb in slice/slice_group: uiSliceIdc (apply in Single/multiple slices and FMO)
  *
- * \param   ppSliceInLayer  slice list in current layer
+ * \param   pCurLayer       current layer
  * \param   kiSliceIdc      slice idc
  *
  * \return  first_mb - successful; -1 - failed;
  */
-int32_t WelsGetFirstMbOfSlice (SSlice** ppSliceInLayer, const int32_t kiSliceIdc);
+int32_t WelsGetFirstMbOfSlice (SDqLayer* pCurLayer, const int32_t kiSliceIdc);
 
 /*!
  * \brief   Get successive mb to be processed in slice/slice_group: uiSliceIdc (apply in Single/multiple slices and FMO)
--- a/codec/encoder/core/inc/svc_encode_slice.h
+++ b/codec/encoder/core/inc/svc_encode_slice.h
@@ -84,10 +84,9 @@
 int32_t AllocMbCacheAligned (SMbCache* pMbCache, CMemoryAlign* pMa);
 void FreeMbCache (SMbCache* pMbCache, CMemoryAlign* pMa);
 
-int32_t InitSliceMBInfo (SSliceArgument* pSliceArgument,
-                         SSlice* pSlice,
-                         const int32_t kiMBWidth,
-                         const int32_t kiMBHeight);
+int32_t InitSliceBoundaryInfo (SDqLayer* pCurLayer, SSliceArgument* pSliceArgument);
+
+int32_t SetSliceBoundaryInfo(SDqLayer* pCurLayer, SSlice* pSlice, const int32_t kiSliceIdx);
 
 int32_t AllocateSliceMBBuffer (SSlice* pSlice, CMemoryAlign* pMa);
 
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -3670,7 +3670,8 @@
     if (SM_SINGLE_SLICE == pParam->sSliceArgument.uiSliceMode) { // only one slice within a sQualityStat layer
       int32_t iSliceSize   = 0;
       int32_t iPayloadSize = 0;
-      SSlice* pCurSlice    = pCtx->pCurDqLayer->ppSliceInLayer[0];
+      uint32_t uiTheadIdx  = 0;
+      SSlice* pCurSlice    = &pCtx->pCurDqLayer->sSliceThreadInfo.pSliceInThread[uiTheadIdx][0];
 
       if (pCtx->bNeedPrefixNalFlag) {
         pCtx->iEncoderError = AddPrefixNal (pCtx, pLayerBsInfo, &pLayerBsInfo->pNalLengthInByte[0], &iNalIdxInLayer, eNalType,
@@ -3682,6 +3683,9 @@
 
       WelsLoadNal (pCtx->pOut, eNalType, eNalRefIdc);
       assert (0 == (int) pCurSlice->uiSliceIdx);
+      pCtx->iEncoderError   = SetSliceBoundaryInfo(pCtx->pCurDqLayer, pCurSlice, 0);
+      WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
+
       pCtx->iEncoderError   = WelsCodeOneSlice (pCtx, pCurSlice, eNalType);
       WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
 
@@ -3805,13 +3809,16 @@
         iLayerSize = AppendSliceToFrameBs (pCtx, pLayerBsInfo, kiPartitionCnt);
       } else { // for non-dynamic-slicing mode single threading branch..
         const bool bNeedPrefix = pCtx->bNeedPrefixNalFlag;
-        int32_t iSliceIdx = 0;
-        SSlice* pCurSlice = NULL;
 
+        int32_t iSliceIdx    = 0;
+        uint32_t uiTheadIdx  = 0;
+        SSlice* pCurSlice    = NULL;
+
         iSliceCount = GetCurrentSliceNum (pCtx->pCurDqLayer);
         while (iSliceIdx < iSliceCount) {
           int32_t iSliceSize    = 0;
           int32_t iPayloadSize  = 0;
+
           if (bNeedPrefix) {
             pCtx->iEncoderError = AddPrefixNal (pCtx, pLayerBsInfo, &pLayerBsInfo->pNalLengthInByte[0], &iNalIdxInLayer, eNalType,
                                                 eNalRefIdc,
@@ -3821,8 +3828,12 @@
           }
 
           WelsLoadNal (pCtx->pOut, eNalType, eNalRefIdc);
-          pCurSlice = pCtx->pCurDqLayer->ppSliceInLayer[iSliceIdx];
+
+          pCurSlice = &pCtx->pCurDqLayer->sSliceThreadInfo.pSliceInThread[uiTheadIdx][iSliceIdx];
           assert (iSliceIdx == (int) pCurSlice->uiSliceIdx);
+          pCtx->iEncoderError   = SetSliceBoundaryInfo(pCtx->pCurDqLayer, pCurSlice, iSliceIdx);
+          WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
+
           pCtx->iEncoderError = WelsCodeOneSlice (pCtx, pCurSlice, eNalType);
           WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
 
@@ -4510,7 +4521,8 @@
                                 ) {
 
   SDqLayer* pCurLayer                   = pCtx->pCurDqLayer;
-  SSlice* pStartSlice                   = pCurLayer->ppSliceInLayer[iStartSliceIdx];
+  uint32_t uiTheadIdx                   = 0;
+  SSlice* pStartSlice                   = &pCurLayer->sSliceThreadInfo.pSliceInThread[uiTheadIdx][iStartSliceIdx];
   int32_t iNalIdxInLayer                = *pNalIdxInLayer;
   int32_t iSliceIdx                     = iStartSliceIdx;
   const int32_t kiSliceStep             = pCtx->iActiveThreadsNum;
@@ -4523,6 +4535,7 @@
   const int32_t kiSliceIdxStep          = pCtx->iActiveThreadsNum;
   int32_t iReturn = ENC_RETURN_SUCCESS;
 
+
   //init
   {
     pStartSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice = iFirstMbIdxInPartition;
@@ -4559,8 +4572,10 @@
     }
 
     WelsLoadNal (pCtx->pOut, keNalType, keNalRefIdc);
-    pCurSlice = pCtx->pCurDqLayer->ppSliceInLayer[iSliceIdx];
+
+    pCurSlice = &pCtx->pCurDqLayer->sSliceThreadInfo.pSliceInThread[uiTheadIdx][iSliceIdx];
     assert (iSliceIdx == (int) pCurSlice->uiSliceIdx);
+
     iReturn = WelsCodeOneSlice (pCtx, pCurSlice, keNalType);
     WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
     WelsUnloadNal (pCtx->pOut);
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -108,12 +108,10 @@
   bool bMultiSliceMode = false;
   int32_t iGomRowMode0 = 1, iGomRowMode1 = 1;
   for (j = 0; j < pEncCtx->pSvcParam->iSpatialLayerNum; j++) {
-    SSliceCtx* pSliceCtx = &pEncCtx->ppDqLayerList[j]->sSliceEncCtx;
     pWelsSvcRc  = &pEncCtx->pWelsSvcRc[j];
     pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[j];
     iMbWidth     = (pDLayerParam->iVideoWidth >> 4);
     pWelsSvcRc->iNumberMbFrame = iMbWidth * (pDLayerParam->iVideoHeight >> 4);
-    pWelsSvcRc->iSliceNum = pSliceCtx->iSliceNumInFrame;
 
     pWelsSvcRc->iRcVaryPercentage = pEncCtx->pSvcParam->iBitsVaryPercentage; // % -- for temp
     pWelsSvcRc->iRcVaryRatio = pWelsSvcRc->iRcVaryPercentage;
@@ -512,28 +510,38 @@
   pEncCtx->iGlobalQp = iLumaQp;
 }
 
-void RcInitSliceInformation (sWelsEncCtx* pEncCtx) {
-  SSlice** ppSliceInLayer       = pEncCtx->pCurDqLayer->ppSliceInLayer;
-  SWelsSvcRc* pWelsSvcRc        = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
-  SRCSlicing* pSOverRc          = &ppSliceInLayer[0]->sSlicingOverRc;
-  const int32_t kiSliceNum      = pWelsSvcRc->iSliceNum;
-  const int32_t kiBitsPerMb     = WELS_DIV_ROUND (static_cast<int64_t> (pWelsSvcRc->iTargetBits) * INT_MULTIPLY,
-                                  pWelsSvcRc->iNumberMbFrame);
+void RCInitOneSliceInformation(sWelsEncCtx* pEncCtx, SSlice* pSlice) {
 
-  for (int32_t i = 0; i < kiSliceNum; i++) {
-    pSOverRc                    = &ppSliceInLayer[i]->sSlicingOverRc;
-    pSOverRc->iStartMbSlice     =
-      pSOverRc->iEndMbSlice     = ppSliceInLayer[i]->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
-    pSOverRc->iEndMbSlice      += (ppSliceInLayer[i]->iCountMbNumInSlice - 1);
-    pSOverRc->iTotalQpSlice     = 0;
-    pSOverRc->iTotalMbSlice     = 0;
-    pSOverRc->iTargetBitsSlice  = WELS_DIV_ROUND (static_cast<int64_t> (kiBitsPerMb) * ppSliceInLayer[i]->iCountMbNumInSlice,
-                                  INT_MULTIPLY);
-    pSOverRc->iFrameBitsSlice   = 0;
-    pSOverRc->iGomBitsSlice     = 0;
+  bool bGomRC = (RC_OFF_MODE == pEncCtx->pSvcParam->iRCMode ||
+                 RC_BUFFERBASED_MODE == pEncCtx->pSvcParam->iRCMode ) ? false : true;
+  if(bGomRC) {
+    SRCSlicing* pSOverRc        = &pSlice->sSlicingOverRc;
+    const int32_t kiBitsPerMb   = pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId].iBitsPerMb;
+    pSOverRc->iStartMbSlice     = pSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
+    pSOverRc->iEndMbSlice       = pSOverRc->iStartMbSlice + pSlice->iCountMbNumInSlice - 1;
+    pSOverRc->iTargetBitsSlice  = WELS_DIV_ROUND (static_cast<int64_t> (kiBitsPerMb) * pSlice->iCountMbNumInSlice,
+                                                  INT_MULTIPLY);
   }
 }
 
+void RcInitSliceInformation (sWelsEncCtx* pEncCtx) {
+  SSlice** ppSliceInLayer   = pEncCtx->pCurDqLayer->ppSliceInLayer;
+  SWelsSvcRc* pWelsSvcRc    = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
+  const int32_t kiSliceNum  = pEncCtx->pCurDqLayer->iMaxSliceNum;
+  pWelsSvcRc->iBitsPerMb    = WELS_DIV_ROUND (static_cast<int64_t> (pWelsSvcRc->iTargetBits) * INT_MULTIPLY,
+                                              pWelsSvcRc->iNumberMbFrame);
+  for (int32_t i = 0; i < kiSliceNum; i++) {
+      SRCSlicing* pSOverRc        = &ppSliceInLayer[i]->sSlicingOverRc;
+      pSOverRc->iTotalQpSlice     = 0;
+      pSOverRc->iTotalMbSlice     = 0;
+      pSOverRc->iFrameBitsSlice   = 0;
+      pSOverRc->iGomBitsSlice     = 0;
+      pSOverRc->iStartMbSlice     = 0;
+      pSOverRc->iEndMbSlice       = 0;
+      pSOverRc->iTargetBitsSlice  = 0;
+  }
+}
+
 void RcDecideTargetBits (sWelsEncCtx* pEncCtx) {
   SWelsSvcRc* pWelsSvcRc        = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
   SRCTemporal* pTOverRc         = &pWelsSvcRc->pTemporalOverRc[pEncCtx->uiTemporalId];
@@ -613,7 +621,7 @@
   SSlice** ppSliceInLayer     = pEncCtx->pCurDqLayer->ppSliceInLayer;
   SWelsSvcRc* pWelsSvcRc      = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
   SRCSlicing* pSOverRc        = &ppSliceInLayer[0]->sSlicingOverRc;
-  const int32_t kiSliceNum    = pWelsSvcRc->iSliceNum;
+  const int32_t kiSliceNum    = pEncCtx->pCurDqLayer->iMaxSliceNum;
   const int32_t kiGlobalQp    = pEncCtx->iGlobalQp;
 
   pWelsSvcRc->iAverageFrameQp = 0;
@@ -700,6 +708,8 @@
   pSOverRc->iGomTargetBits = iAllocateBits;
 }
 
+
+
 void RcCalculateGomQp (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb) {
   SWelsSvcRc* pWelsSvcRc    = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
   SRCSlicing* pSOverRc      = &pSlice->sSlicingOverRc;
@@ -1125,7 +1135,8 @@
 }
 
 void  WelsRcPictureInitGom (sWelsEncCtx* pEncCtx, long long uiTimeStamp) {
-  SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
+  SWelsSvcRc* pWelsSvcRc           = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
+  const int32_t kiSliceNum         = pEncCtx->pCurDqLayer->iMaxSliceNum;
   pWelsSvcRc->iContinualSkipFrames = 0;
 
   if (pEncCtx->eSliceType == I_SLICE) {
@@ -1146,7 +1157,7 @@
     RcDecideTargetBits (pEncCtx);
   }
   //turn off GOM QP when slicenum is larger 1
-  if ((pWelsSvcRc->iSliceNum > 1) || ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE)
+  if ((kiSliceNum > 1) || ((pEncCtx->pSvcParam->iRCMode == RC_BITRATE_MODE)
                                       && (pEncCtx->eSliceType == I_SLICE))) {
     pWelsSvcRc->bEnableGomQp = false;
   } else
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -81,10 +81,9 @@
                                    SMB* pMbList,
                                    const int32_t uiSliceIdc) {
   SSliceCtx* pSliceCtx           = &pCurDq->sSliceEncCtx;
-  SSlice* pUpdateSlice           = pCurDq->ppSliceInLayer[uiSliceIdc];
   const int32_t kiMbWidth        = pSliceCtx->iMbWidth;
-  int32_t iIdx                   = pUpdateSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
-  const int32_t kiEndMbInSlice   = iIdx + pUpdateSlice->iCountMbNumInSlice - 1;
+  int32_t iIdx                   = pCurDq->pFirstMbIdxOfSlice[uiSliceIdc];
+  const int32_t kiEndMbInSlice   = iIdx + pCurDq->pCountMbNumInSlice[uiSliceIdc] - 1;
 
   do {
     UpdateMbNeighbor (pCurDq, &pMbList[iIdx], kiMbWidth, uiSliceIdc);
@@ -604,9 +603,9 @@
       if (pParamD->sSliceArgument.uiSliceMode != SM_SIZELIMITED_SLICE) {
         int64_t iSliceStart = 0;
         bool bDsaFlag = false;
-        iSliceIdx               = pPrivateData->iSliceIndex;
-        pSlice                  = pCurDq->ppSliceInLayer[iSliceIdx];
-        pSliceBs                = &pSlice->sSliceBs;
+        iSliceIdx     = pPrivateData->iSliceIndex;
+        pSlice        = &pCurDq->sSliceThreadInfo.pSliceInThread[iThreadIdx][iSliceIdx];
+        pSliceBs      = &pSlice->sSliceBs;
 
         bDsaFlag = ((pParamD->sSliceArgument.uiSliceMode == SM_FIXEDSLCNUM_SLICE) &&
                     pCodingParam->iMultipleThreadIdc > 1 &&
@@ -638,7 +637,7 @@
         WelsLoadNalForSlice (pSliceBs, eNalType, eNalRefIdc);
         pCurSlice = pEncPEncCtx->pCurDqLayer->ppSliceInLayer[iSliceIdx];
         assert (iSliceIdx == (int) pCurSlice->uiSliceIdx);
-        iReturn = WelsCodeOneSlice (pEncPEncCtx, pCurSlice, eNalType);
+        iReturn = SetSliceBoundaryInfo(pEncPEncCtx->pCurDqLayer, pCurSlice, iSliceIdx);
         if (ENC_RETURN_SUCCESS != iReturn) {
           uiThrdRet = iReturn;
           WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
@@ -646,6 +645,23 @@
                                         iEventIdx);
         }
 
+        iReturn = SetSliceBoundaryInfo(pEncPEncCtx->pCurDqLayer, pSlice, iSliceIdx);
+        if (ENC_RETURN_SUCCESS != iReturn) {
+          uiThrdRet = iReturn;
+          WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
+                                        pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent,
+                                        iEventIdx);
+        }
+
+        assert (iSliceIdx == (int) pSlice->uiSliceIdx);
+        iReturn = WelsCodeOneSlice (pEncPEncCtx, pSlice, eNalType);
+        if (ENC_RETURN_SUCCESS != iReturn) {
+          uiThrdRet = iReturn;
+          WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
+                                        pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent,
+                                        iEventIdx);
+        }
+
         WelsUnloadNalForSlice (pSliceBs);
 
         iReturn    = WriteSliceBs (pEncPEncCtx, pSliceBs, iSliceIdx, iSliceSize);
@@ -659,14 +675,13 @@
         pEncPEncCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (pCurDq, pEncPEncCtx->pFuncList, iSliceIdx);
 
         if (bDsaFlag) {
-            pEncPEncCtx->pCurDqLayer->ppSliceInLayer[iSliceIdx]->uiSliceConsumeTime = (uint32_t) (
-                WelsTime() - iSliceStart);
+          pSlice->uiSliceConsumeTime = (uint32_t) (WelsTime() - iSliceStart);
           MT_TRACE_LOG (& (pEncPEncCtx->sLogCtx), WELS_LOG_INFO,
                         "[MT] CodingSliceThreadProc(), coding_idx %d, uiSliceIdx %d, uiSliceConsumeTime %d, iSliceSize %d, iFirstMbInSlice %d, count_num_mb_in_slice %d",
                         pEncPEncCtx->iCodingIndex, iSliceIdx,
-                        pEncPEncCtx->pCurDqLayer->ppSliceInLayer[iSliceIdx]->uiSliceConsumeTime, iSliceSize,
-                        pCurDq->ppSliceInLayer[iSliceIdx]->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice,
-                        pCurDq->ppSliceInLayer[iSliceIdx]->iCountMbNumInSlice);
+                        pSlice->uiSliceConsumeTime, iSliceSize,
+                        pSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice,
+                        pSlice->iCountMbNumInSlice);
         }
 
 #if defined(SLICE_INFO_OUTPUT)
@@ -694,11 +709,11 @@
         const int32_t kiEndMbIdxInPartition     = pCurDq->pEndMbIdxOfPartition[kiPartitionId];
         int32_t iAnyMbLeftInPartition           = kiEndMbIdxInPartition - kiFirstMbInPartition + 1;
         SSpatialLayerInternal *pParamInternal   = &pCodingParam->sDependencyLayers[kiCurDid];
-        iSliceIdx = pPrivateData->iSliceIndex;
-        SSliceHeaderExt* pStartSliceHeaderExt                   = &pCurDq->ppSliceInLayer[iSliceIdx]->sSliceHeaderExt;
-        pStartSliceHeaderExt->sSliceHeader.iFirstMbInSlice      = kiFirstMbInPartition;
-        pCurDq->pNumSliceCodedOfPartition[kiPartitionId]        = 1;
-        pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]       = 0;
+        iSliceIdx                               = pPrivateData->iSliceIndex;
+        SSlice* pStartSlice                     = &pCurDq->sSliceThreadInfo.pSliceInThread[iThreadIdx][iSliceIdx];
+        pStartSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice = kiFirstMbInPartition;
+        pCurDq->pNumSliceCodedOfPartition[kiPartitionId]          = 1;
+        pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]         = 0;
 
         while (iAnyMbLeftInPartition > 0) {
           if (iSliceIdx >= pCurDq->iMaxSliceNum) {
@@ -713,8 +728,7 @@
                                           pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent,
                                           iEventIdx);
           }
-
-          pSlice = pCurDq->ppSliceInLayer[iSliceIdx];
+          pSlice                = &pCurDq->sSliceThreadInfo.pSliceInThread[iThreadIdx][iSliceIdx];
           pSliceBs              = &pSlice->sSliceBs;
           pSliceBs->uiBsPos     = 0;
           pSliceBs->iNalIndex   = 0;
@@ -734,11 +748,10 @@
             }
           }
 
-
           WelsLoadNalForSlice (pSliceBs, eNalType, eNalRefIdc);
-          pCurSlice = pEncPEncCtx->pCurDqLayer->ppSliceInLayer[iSliceIdx];
-          assert (iSliceIdx == (int) pCurSlice->uiSliceIdx);
-          iReturn = WelsCodeOneSlice (pEncPEncCtx, pCurSlice, eNalType);
+
+          assert (iSliceIdx == (int) pSlice->uiSliceIdx);
+          iReturn = WelsCodeOneSlice (pEncPEncCtx, pSlice, eNalType);
           if (ENC_RETURN_SUCCESS != iReturn) {
             uiThrdRet = iReturn;
             WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
@@ -776,7 +789,7 @@
           MT_TRACE_LOG (& (pEncPEncCtx->sLogCtx), WELS_LOG_INFO,
                         "[MT] CodingSliceThreadProc(), coding_idx %d, iPartitionId %d, uiSliceIdx %d, iSliceSize %d, count_mb_slice %d, iEndMbInPartition %d, pCurDq->pLastCodedMbIdxOfPartition[%d] %d\n",
                         pEncPEncCtx->iCodingIndex, kiPartitionId, iSliceIdx, iSliceSize,
-                        pCurDq->ppSliceInLayer[iSliceIdx]->iCountMbNumInSlice,
+                        pSlice->iCountMbNumInSlice,
                         kiEndMbIdxInPartition, kiPartitionId, pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]);
 
           iAnyMbLeftInPartition = kiEndMbIdxInPartition - pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId];
--- a/codec/encoder/core/src/svc_enc_slice_segment.cpp
+++ b/codec/encoder/core/src/svc_enc_slice_segment.cpp
@@ -527,17 +527,17 @@
 /*!
  * \brief   Get first mb in slice/slice_group: uiSliceIdc (apply in Single/multiple slices and FMO)
  *
- * \param   ppSliceInLayer  slice list in current layer
+ * \param   pCurLayer       current layer
  * \param   kuiSliceIdc     slice idc
  *
  * \return  iFirstMb - successful; -1 - failed;
  */
-int32_t WelsGetFirstMbOfSlice (SSlice** ppSliceInLayer, const int32_t kuiSliceIdc) {
-  if ( NULL == ppSliceInLayer || NULL == ppSliceInLayer[kuiSliceIdc] ) {
+int32_t WelsGetFirstMbOfSlice (SDqLayer* pCurLayer, const int32_t kuiSliceIdc) {
+  if ( NULL == pCurLayer || NULL == pCurLayer->pFirstMbIdxOfSlice ) {
     return -1;
   }
 
-  return ppSliceInLayer[kuiSliceIdc]->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
+  return pCurLayer->pFirstMbIdxOfSlice[kuiSliceIdc];
 }
 
 /*!
@@ -637,7 +637,6 @@
 int32_t DynamicAdjustSlicePEncCtxAll (SDqLayer* pCurDq,
                                       int32_t* pRunLength) {
   SSliceCtx* pSliceCtx                  = &pCurDq->sSliceEncCtx;
-  SSlice** ppSliceInLayer               = pCurDq->ppSliceInLayer;
   const int32_t iCountNumMbInFrame      = pSliceCtx->iMbNumInFrame;
   const int32_t iCountSliceNumInFrame   = pSliceCtx->iSliceNumInFrame;
   int32_t iSameRunLenFlag               = 1;
@@ -647,7 +646,7 @@
   assert (iCountSliceNumInFrame <= MAX_THREADS_NUM);
 
   while (iSliceIdx < iCountSliceNumInFrame) {
-    if (pRunLength[iSliceIdx] != ppSliceInLayer[iSliceIdx]->iCountMbNumInSlice) {
+    if (pRunLength[iSliceIdx] != pCurDq->pFirstMbIdxOfSlice[iSliceIdx]) {
       iSameRunLenFlag = 0;
       break;
     }
@@ -660,9 +659,6 @@
   iSliceIdx = 0;
   do {
     const int32_t kiSliceRun = pRunLength[iSliceIdx];
-    SSliceHeaderExt* pSliceHeaderExt              = &ppSliceInLayer[iSliceIdx]->sSliceHeaderExt;
-    pSliceHeaderExt->sSliceHeader.iFirstMbInSlice = iFirstMbIdx;
-    ppSliceInLayer[iSliceIdx]->iCountMbNumInSlice = kiSliceRun;
     pCurDq->pFirstMbIdxOfSlice[iSliceIdx]         = iFirstMbIdx;
     pCurDq->pCountMbNumInSlice[iSliceIdx]         = kiSliceRun;
 
--- a/codec/encoder/core/src/svc_encode_slice.cpp
+++ b/codec/encoder/core/src/svc_encode_slice.cpp
@@ -94,8 +94,6 @@
 
   pCurSliceExt->bStoreRefBasePicFlag = false;
 
-  pCurSliceHeader->iFirstMbInSlice = WelsGetFirstMbOfSlice (pCurLayer->ppSliceInLayer, pSlice->uiSliceIdx);
-
   pCurSliceHeader->iFrameNum      = pParamInternal->iFrameNum;
   pCurSliceHeader->uiIdrPicId     = pParamInternal->uiIdrPicId;
   pCurSliceHeader->iPicOrderCntLsb = pEncCtx->pEncPic->iFramePoc;      // 0
@@ -814,49 +812,64 @@
   }
 }
 
-//Initialize slice's MB info)
-int32_t InitSliceMBInfo (SSliceArgument* pSliceArgument,
-                         SSlice* pSlice,
-                         const int32_t kiMBWidth,
-                         const int32_t kiMBHeight) {
-  SSliceHeader* pSliceHeader          = &pSlice->sSliceHeaderExt.sSliceHeader;
+//Initialize slice's boundary info)
+int32_t InitSliceBoundaryInfo (SDqLayer* pCurLayer, SSliceArgument* pSliceArgument) {
+
   const int32_t* kpSlicesAssignList   = (int32_t*) & (pSliceArgument->uiSliceMbNum[0]);
+  const int32_t kiMBWidth             = pCurLayer->iMbWidth;
+  const int32_t kiMBHeight            = pCurLayer->iMbHeight;
   const int32_t kiCountNumMbInFrame   = kiMBWidth * kiMBHeight;
-  const int32_t kiSliceIdx            = pSlice->uiSliceIdx;
+  int32_t iSliceIdx                   = 0;
   int32_t iFirstMBInSlice             = 0;
   int32_t iMbNumInSlice               = 0;
 
-  if (SM_SINGLE_SLICE == pSliceArgument->uiSliceMode) {
-    iFirstMBInSlice = 0;
-    iMbNumInSlice   = kiCountNumMbInFrame;
+  for( ;iSliceIdx < pCurLayer->iMaxSliceNum; iSliceIdx++ ){
+    if (SM_SINGLE_SLICE == pSliceArgument->uiSliceMode) {
+      iFirstMBInSlice = 0;
+      iMbNumInSlice   = kiCountNumMbInFrame;
 
-  } else if ((SM_RASTER_SLICE == pSliceArgument->uiSliceMode) && (0 == pSliceArgument->uiSliceMbNum[0])) {
-    iFirstMBInSlice = kiSliceIdx * kiMBWidth;
-    iMbNumInSlice   = kiMBWidth;
-  } else if (SM_RASTER_SLICE  == pSliceArgument->uiSliceMode ||
+    } else if ((SM_RASTER_SLICE == pSliceArgument->uiSliceMode) && (0 == pSliceArgument->uiSliceMbNum[0])) {
+      iFirstMBInSlice = iSliceIdx * kiMBWidth;
+      iMbNumInSlice   = kiMBWidth;
+    } else if (SM_RASTER_SLICE  == pSliceArgument->uiSliceMode ||
              SM_FIXEDSLCNUM_SLICE == pSliceArgument->uiSliceMode) {
-    int32_t iMbIdx  = 0;
-    for (int i = 0; i < kiSliceIdx; i++) {
-      iMbIdx += kpSlicesAssignList[i];
-    }
+      int32_t iMbIdx  = 0;
+      for (int i = 0; i < iSliceIdx; i++) {
+        iMbIdx += kpSlicesAssignList[i];
+      }
 
-    if (iMbIdx >= kiCountNumMbInFrame) {
-      return ENC_RETURN_UNEXPECTED;
+      if (iMbIdx >= kiCountNumMbInFrame) {
+        return ENC_RETURN_UNEXPECTED;
+      }
+
+      iFirstMBInSlice = iMbIdx;
+      iMbNumInSlice   = kpSlicesAssignList[iSliceIdx];
+
+    } else if (SM_SIZELIMITED_SLICE == pSliceArgument->uiSliceMode) {
+      iFirstMBInSlice  = 0;
+      iMbNumInSlice    = kiCountNumMbInFrame;
+
+    } else { // any else uiSliceMode?
+      assert (0);
     }
 
-    iFirstMBInSlice = iMbIdx;
-    iMbNumInSlice   = kpSlicesAssignList[kiSliceIdx];
+    pCurLayer->pCountMbNumInSlice[iSliceIdx] = iMbNumInSlice;
+    pCurLayer->pFirstMbIdxOfSlice[iSliceIdx] = iFirstMBInSlice;
+  }
 
-  } else if (SM_SIZELIMITED_SLICE == pSliceArgument->uiSliceMode) {
-    iFirstMBInSlice  = 0;
-    iMbNumInSlice    = kiCountNumMbInFrame;
+  return ENC_RETURN_SUCCESS;
+}
 
-  } else { // any else uiSliceMode?
-    assert (0);
+int32_t SetSliceBoundaryInfo(SDqLayer* pCurLayer, SSlice* pSlice, const int32_t kiSliceIdx) {
+  if(NULL == pCurLayer || NULL == pSlice  ||
+    NULL == pCurLayer->pFirstMbIdxOfSlice ||
+    NULL == pCurLayer->pCountMbNumInSlice) {
+
+    return ENC_RETURN_UNEXPECTED;
   }
 
-  pSlice->iCountMbNumInSlice    = iMbNumInSlice;
-  pSliceHeader->iFirstMbInSlice = iFirstMBInSlice;
+  pSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice = pCurLayer->pFirstMbIdxOfSlice[kiSliceIdx];
+  pSlice->iCountMbNumInSlice  = pCurLayer->pCountMbNumInSlice[kiSliceIdx];
 
   return ENC_RETURN_SUCCESS;
 }
@@ -941,9 +954,12 @@
     }
 
     pSlice->uiSliceIdx = iSliceIdx;
+    pSlice->uiThreadIdx = 0;
+    pSlice->iCountMbNumInSlice = 0;
+    pSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice = 0;
 
     iRet = InitSliceBsBuffer (pSlice,
-                              & pCtx->pOut->sBsWrite,
+                              &pCtx->pOut->sBsWrite,
                               bIndependenceBsBuffer,
                               iMaxSliceBufferSize,
                               pMa);
@@ -951,12 +967,6 @@
       return iRet;
     }
 
-    iRet = InitSliceMBInfo (pSliceArgument, pSlice,
-                            kiMBWidth, kiMBHeight);
-
-    if (ENC_RETURN_SUCCESS != iRet) {
-      return iRet;
-    }
     iRet = AllocateSliceMBBuffer (pSlice, pMa);
 
     if (ENC_RETURN_SUCCESS != iRet) {
@@ -993,11 +1003,6 @@
   pSlice->sSliceBs.iNalIndex = 0;
   pSlice->sSliceBs.pBsBuffer = pCtx->pSliceThreading->pThreadBsBuffer[kiThreadIdx];
 
-  // init slice MB info
-  iRet = InitSliceMBInfo (pSliceArgument, pSlice, kiMBWidth, kiMBHeight);
-  if (ENC_RETURN_SUCCESS != iRet) {
-    return iRet;
-  }
   return ENC_RETURN_SUCCESS;
 }
 */
@@ -1073,6 +1078,11 @@
     return ENC_RETURN_MEMALLOCERR;
   }
 
+  iRet = InitSliceBoundaryInfo (pDqLayer, &pCtx->pSvcParam->sSpatialLayers[kiDlayerIndex].sSliceArgument);
+  if (ENC_RETURN_SUCCESS != iRet) {
+    return iRet;
+  }
+
   InitSliceThreadInfo (pCtx,
                        pDqLayer,
                        kiDlayerIndex,
@@ -1118,9 +1128,9 @@
 
 }
 
-static inline int32_t InitSliceRC (SSlice* pSlice, const int32_t kiGlobalQp, const int32_t kiBitsPerMb) {
+static inline int32_t InitSliceRC (SSlice* pSlice, const int32_t kiGlobalQp) {
 
-  if (NULL == pSlice || kiGlobalQp < 0 ||  kiBitsPerMb < 0)
+  if (NULL == pSlice || kiGlobalQp < 0)
     return ENC_RETURN_INVALIDINPUT;
 
   pSlice->sSlicingOverRc.iComplexityIndexSlice = 0;
@@ -1127,9 +1137,7 @@
   pSlice->sSlicingOverRc.iCalculatedQpSlice    = kiGlobalQp;
   pSlice->sSlicingOverRc.iTotalQpSlice         = 0;
   pSlice->sSlicingOverRc.iTotalMbSlice         = 0;
-  pSlice->sSlicingOverRc.iTargetBitsSlice      = WELS_DIV_ROUND (kiBitsPerMb *
-      pSlice->iCountMbNumInSlice,
-      INT_MULTIPLY);
+  pSlice->sSlicingOverRc.iTargetBitsSlice      = 0;
   pSlice->sSlicingOverRc.iFrameBitsSlice       = 0;
   pSlice->sSlicingOverRc.iGomBitsSlice         = 0;
 
@@ -1142,7 +1150,6 @@
                              const int32_t kiMaxSliceNumOld,
                              const int32_t kiMaxSliceNumNew) {
   CMemoryAlign* pMA           = pCtx->pMemAlign;
-  SDqLayer* pCurLayer         = pCtx->pCurDqLayer;
   SSlice* pBaseSlice          = NULL;
   SSlice* pNewSliceList       = NULL;
   SSlice* pSlice              = NULL;
@@ -1150,8 +1157,6 @@
   int32_t iRet                = 0;
   const int32_t kiCurDid      = pCtx->uiDependencyId;
   int32_t iMaxSliceBufferSize = (pCtx)->iSliceBufferSize[kiCurDid];
-  int32_t iBitsPerMb          = WELS_DIV_ROUND (pCtx->pWelsSvcRc[kiCurDid].iTargetBits * INT_MULTIPLY,
-                                pCtx->pWelsSvcRc[kiCurDid].iNumberMbFrame);
   bool bIndependenceBsBuffer  = (pCtx->pSvcParam->iMultipleThreadIdc > 1 &&
                                  SM_SINGLE_SLICE != pSliceArgument->uiSliceMode) ? true : false;
 
@@ -1181,6 +1186,9 @@
     }
 
     pSlice->uiSliceIdx = iSliceIdx;
+    pSlice->uiThreadIdx = 0;
+    pSlice->iCountMbNumInSlice = 0;
+    pSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice = 0;
 
     iRet = InitSliceBsBuffer (pSlice,
                               & pCtx->pOut->sBsWrite,
@@ -1198,19 +1206,10 @@
       return iRet;
     }
 
-    iRet = InitSliceMBInfo (pSliceArgument,
-                            pSlice,
-                            pCurLayer->iMbWidth,
-                            pCurLayer->iMbHeight);
-    if (ENC_RETURN_SUCCESS != iRet) {
-      FreeSliceBuffer(pNewSliceList, kiMaxSliceNumNew, pMA, "ReallocateSliceList()::InitSliceBsBuffer()");
-      return iRet;
-    }
-
     InitSliceHeadWithBase (pSlice, pBaseSlice);
     InitSliceRefInfoWithBase (pSlice, pBaseSlice, pCtx->iNumRef0);
 
-    iRet = InitSliceRC (pSlice, pCtx->iGlobalQp, iBitsPerMb);
+    iRet = InitSliceRC (pSlice, pCtx->iGlobalQp);
     if (ENC_RETURN_SUCCESS != iRet) {
       FreeSliceBuffer(pNewSliceList, kiMaxSliceNumNew, pMA, "ReallocateSliceList()::InitSliceBsBuffer()");
       return iRet;
@@ -1344,6 +1343,7 @@
   pMA->WelsFree (pCurLayer->pCountMbNumInSlice, "pCountMbNumInSlice");
   pCurLayer->pCountMbNumInSlice = pCountMbNumInSlice;
 
+
   for (iSliceIdx = 0; iSliceIdx < iMaxSliceNumNew; iSliceIdx++) {
     pCurLayer->ppSliceInLayer[iSliceIdx] = pCurLayer->sSliceThreadInfo.pSliceInThread[0] + iSliceIdx;
   }
@@ -1356,7 +1356,6 @@
   pCurLayer->iMaxSliceNum = iMaxSliceNumNew;
   return ENC_RETURN_SUCCESS;
 }
-
 /*
 int32_t ReOrderSliceInLayer (SDqLayer* pCurLayer,
                              const int32_t kiThreadNum,
@@ -1477,6 +1476,9 @@
 
   WelsSliceHeaderExtInit (pEncCtx, pCurLayer, pCurSlice);
 
+  //init slice RC information
+  RCInitOneSliceInformation(pEncCtx, pCurSlice);
+
   g_pWelsWriteSliceHeader[pCurSlice->bSliceHeaderExtFlag] (pEncCtx, pBs, pCurLayer, pCurSlice,
       pEncCtx->pFuncList->pParametersetStrategy);
 
@@ -1517,7 +1519,7 @@
 void AddSliceBoundary (sWelsEncCtx* pEncCtx, SSlice* pCurSlice, SSliceCtx* pSliceCtx, SMB* pCurMb,
                        int32_t iFirstMbIdxOfNextSlice, const int32_t kiLastMbIdxInPartition) {
   SDqLayer*     pCurLayer       = pEncCtx->pCurDqLayer;
-  SSlice**      ppSliceInLayer  = pCurLayer->ppSliceInLayer;
+  SSlice*       pSliceInThread  = pCurLayer->sSliceThreadInfo.pSliceInThread[0];
   int32_t       iCurMbIdx       = pCurMb->iMbXY;
   uint16_t      iCurSliceIdc    = pSliceCtx->pOverallMbMap[ iCurMbIdx ];
   const int32_t kiSliceIdxStep  = pEncCtx->iActiveThreadsNum;
@@ -1530,7 +1532,7 @@
   pCurSlice->sSliceHeaderExt.uiNumMbsInSlice = 1 + iCurMbIdx - pCurSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
 
   //pNextSlice pointer/initialization
-  pNextSlice = pCurLayer->ppSliceInLayer[ iNextSliceIdc ];
+  pNextSlice = &pSliceInThread[ iNextSliceIdc ];
 
 #if _DEBUG
   assert (NULL != pNextSlice);
@@ -1541,7 +1543,7 @@
     (NAL_UNIT_CODED_SLICE_EXT == pCurLayer->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType);
   memcpy (&pNextSlice->sSliceHeaderExt, &pCurSlice->sSliceHeaderExt,
           sizeof (SSliceHeaderExt)); // confirmed_safe_unsafe_usage
-  ppSliceInLayer[iNextSliceIdc]->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice = iFirstMbIdxOfNextSlice;
+  pNextSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice = iFirstMbIdxOfNextSlice;
   WelsSetMemMultiplebytes_c (pSliceCtx->pOverallMbMap + iFirstMbIdxOfNextSlice, iNextSliceIdc,
                              (kiLastMbIdxInPartition - iFirstMbIdxOfNextSlice + 1), sizeof (uint16_t));
 
--- a/codec/encoder/core/src/wels_task_encoder.cpp
+++ b/codec/encoder/core/src/wels_task_encoder.cpp
@@ -113,12 +113,15 @@
   }
 
   //  InitOneSliceInThread();
-  m_pSlice   = m_pCtx->pCurDqLayer->ppSliceInLayer[m_iSliceIdx];
+  m_pSlice = &m_pCtx->pCurDqLayer->sSliceThreadInfo.pSliceInThread[0][m_iSliceIdx];
   m_pSliceBs = &m_pSlice->sSliceBs;
 
   m_pSliceBs->uiBsPos       = 0;
   m_pSliceBs->iNalIndex     = 0;
 
+  m_pCtx->iEncoderError   = SetSliceBoundaryInfo(m_pCtx->pCurDqLayer, m_pSlice, m_iSliceIdx);
+  WELS_VERIFY_RETURN_IFNEQ (m_pCtx->iEncoderError, ENC_RETURN_SUCCESS)
+
   SetOneSliceBsBufferUnderMultithread (m_pCtx, m_iThreadIdx, m_pSlice);
 
   assert ((void*) (&m_pSliceBs->sBsWrite) == (void*)m_pSlice->pSliceBsa);
@@ -163,9 +166,9 @@
   }
 
   WelsLoadNalForSlice (m_pSliceBs, m_eNalType, m_eNalRefIdc);
-  SSlice* pCurSlice    = m_pCtx->pCurDqLayer->ppSliceInLayer[m_iSliceIdx];
-  assert (m_iSliceIdx == (int) pCurSlice->uiSliceIdx);
-  int32_t iReturn = WelsCodeOneSlice (m_pCtx, pCurSlice, m_eNalType);
+
+  assert (m_iSliceIdx == (int) m_pSlice->uiSliceIdx);
+  int32_t iReturn = WelsCodeOneSlice (m_pCtx, m_pSlice, m_eNalType);
   if (ENC_RETURN_SUCCESS != iReturn) {
     return iReturn;
   }
@@ -236,11 +239,11 @@
   SSliceCtx* pSliceCtx                    = &pCurDq->sSliceEncCtx;
   const int32_t kiSliceIdxStep            = m_pCtx->iActiveThreadsNum;
   SSpatialLayerInternal* pParamInternal   = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];
-  SSliceHeaderExt* pStartSliceHeaderExt   = &pCurDq->ppSliceInLayer[m_iSliceIdx]->sSliceHeaderExt;
   const int32_t kiPartitionId             = m_iSliceIdx % kiSliceIdxStep;
   const int32_t kiFirstMbInPartition      = pCurDq->pFirstMbIdxOfPartition[kiPartitionId];
   const int32_t kiEndMbIdxInPartition     = pCurDq->pEndMbIdxOfPartition[kiPartitionId];
-  pStartSliceHeaderExt->sSliceHeader.iFirstMbInSlice      = kiFirstMbInPartition;
+  m_pSlice                                = &pCurDq->sSliceThreadInfo.pSliceInThread[0][m_iSliceIdx];
+  m_pSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice  = kiFirstMbInPartition;
   pCurDq->pNumSliceCodedOfPartition[kiPartitionId]        = 1;
   pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]       = 0;
 
@@ -258,7 +261,7 @@
       return ENC_RETURN_KNOWN_ISSUE;
     }
 
-    m_pSlice = pCurDq->ppSliceInLayer[iLocalSliceIdx];
+    m_pSlice = &pCurDq->sSliceThreadInfo.pSliceInThread[0][iLocalSliceIdx];
     m_pSliceBs = &m_pSlice->sSliceBs;
 
     m_pSliceBs->uiBsPos     = 0;
@@ -280,9 +283,9 @@
     }
 
     WelsLoadNalForSlice (m_pSliceBs, m_eNalType, m_eNalRefIdc);
-    SSlice* pCurSlice    = m_pCtx->pCurDqLayer->ppSliceInLayer[iLocalSliceIdx];
-    assert (iLocalSliceIdx == (int) pCurSlice->uiSliceIdx);
-    int32_t iReturn = WelsCodeOneSlice (m_pCtx, pCurSlice, m_eNalType);
+
+    assert (iLocalSliceIdx == (int) m_pSlice->uiSliceIdx);
+    int32_t iReturn = WelsCodeOneSlice (m_pCtx, m_pSlice, m_eNalType);
     if (ENC_RETURN_SUCCESS != iReturn) {
       return iReturn;
     }