shithub: openh264

Download patch

ref: 268e6cf09f5d608da62c0fad3cc1922b87a0ea6e
parent: f9d8e9a76e4d29f98960bb3ab015e648c121d226
parent: 35ab32b1a32413bef094da9c94e6cb8d9cb34aff
author: HaiboZhu <haibozhu@cisco.com>
date: Thu Nov 19 08:13:01 EST 2015

Merge pull request #2255 from shihuade/MultiThread_V4.1_SliceCtx_V3_Pull_V3

remove (ppCtx)->pSliceCtxList and only keep DqLayer->sSliceCtx 

--- a/codec/encoder/core/inc/encoder_context.h
+++ b/codec/encoder/core/inc/encoder_context.h
@@ -137,9 +137,7 @@
   SSliceThreading*  pSliceThreading;
   IWelsTaskManage*  pTaskManage; //was planning to put it under CWelsH264SVCEncoder but it may be updated (lock/no lock) when param is changed
 
-// SSlice context
-  SSliceCtx*        pSliceCtxList;// slice context table for each dependency quality layer
-// pointers
+  // pointers
   SPicture*         pEncPic;                // pointer to current picture to be encoded
   SPicture*         pDecPic;                // pointer to current picture being reconstructed
   SPicture*         pRefPic;                // pointer to current reference picture
--- a/codec/encoder/core/inc/svc_enc_frame.h
+++ b/codec/encoder/core/inc/svc_enc_frame.h
@@ -79,7 +79,7 @@
 /* Layer Representation */
 struct TagDqLayer {
 SLayerInfo              sLayerInfo;
-
+SSliceCtx               sSliceEncCtx;   // current slice context
 uint8_t*                pCsData[3];     // pointer to reconstructed picture pData
 int32_t                 iCsStride[3];   // Cs stride
 
@@ -104,8 +104,6 @@
 SPicture*               pRefPic;        // reference picture pointer
 SPicture*               pDecPic;        // reconstruction picture pointer for layer
 SPicture*               pRefOri[MAX_REF_PIC_COUNT];
-
-SSliceCtx*              pSliceEncCtx;   // current slice context
 
 int32_t*                pNumSliceCodedOfPartition;      // for dynamic slicing mode
 int32_t*                pLastCodedMbIdxOfPartition;     // for dynamic slicing mode
--- a/codec/encoder/core/src/deblocking.cpp
+++ b/codec/encoder/core/src/deblocking.cpp
@@ -691,7 +691,7 @@
 }
 
 void DeblockingFilterSliceAvcbase (SDqLayer* pCurDq, SWelsFuncPtrList* pFunc, const int32_t kiSliceIdx) {
-  SSliceCtx* pSliceCtx                  = pCurDq->pSliceEncCtx;
+  SSliceCtx* pSliceCtx                  = &pCurDq->sSliceEncCtx;
   SMB* pMbList                          = pCurDq->sMbDataP;
   SSliceHeaderExt* sSliceHeaderExt      = &pCurDq->sLayerInfo.pSliceInLayer[kiSliceIdx].sSliceHeaderExt;
   SMB* pCurrentMbBlock;
@@ -755,7 +755,7 @@
     int32_t iSliceIdx   = 0;
 
     if (SM_SIZELIMITED_SLICE != pSpatialLayer->sSliceArgument.uiSliceMode) {
-      iSliceCount = GetCurrentSliceNum (pCurLayer->pSliceEncCtx);
+      iSliceCount = GetCurrentSliceNum (&pCurLayer->sSliceEncCtx);
       do {
         DeblockingFilterSliceAvcbase (pCurLayer, pEnc->pFuncList, iSliceIdx);
         ++ iSliceIdx;
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -764,7 +764,7 @@
   int32_t  iMbHeight    = pLayer->iMbHeight;
   int32_t  iIdx;
   int32_t  iMbNum       = iMbWidth * iMbHeight;
-  SSliceCtx* pSliceCtx = pLayer->pSliceEncCtx;
+  SSliceCtx* pSliceCtx  = &pLayer->sSliceEncCtx;
   uint32_t uiNeighborAvail;
   const int32_t kiOffset = (kiDlayerId & 0x01) * kiMaxMbNum;
   SMVUnitXY (*pLayerMvUnitBlock4x4)[MB_BLOCK4x4_NUM] = (SMVUnitXY (*)[MB_BLOCK4x4_NUM]) (
@@ -1361,7 +1361,7 @@
 
     // Not using FMO in SVC coding so far, come back if need FMO
     {
-      iResult = InitSlicePEncCtx (& (*ppCtx)->pSliceCtxList[iDlayerIndex],
+      iResult = InitSlicePEncCtx (&(*ppCtx)->ppDqLayerList[iDlayerIndex]->sSliceEncCtx,
                                   (*ppCtx)->pMemAlign,
                                   false,
                                   pSps->iMbWidth,
@@ -1373,7 +1373,6 @@
         FreeMemorySvc (ppCtx);
         return iResult;
       }
-      (*ppCtx)->ppDqLayerList[iDlayerIndex]->pSliceEncCtx = & (*ppCtx)->pSliceCtxList[iDlayerIndex];
     }
     pDqIdc->iSpsId = iSpsId;
     pDqIdc->iPpsId = iPpsId;
@@ -1860,10 +1859,6 @@
   (*ppCtx)->ppRefPicListExt = (SRefList**)pMa->WelsMalloc (kiNumDependencyLayers * sizeof (SRefList*), "ppRefPicListExt");
   WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->ppRefPicListExt), FreeMemorySvc (ppCtx))
 
-  // pSlice context list
-  (*ppCtx)->pSliceCtxList = (SSliceCtx*)pMa->WelsMallocz (kiNumDependencyLayers * sizeof (SSliceCtx), "pSliceCtxList");
-  WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSliceCtxList), FreeMemorySvc (ppCtx))
-
   (*ppCtx)->ppDqLayerList = (SDqLayer**)pMa->WelsMalloc (kiNumDependencyLayers * sizeof (SDqLayer*), "ppDqLayerList");
   WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->ppDqLayerList), FreeMemorySvc (ppCtx))
 
@@ -2096,8 +2091,8 @@
             int32_t iSliceIdx = 0;
             int32_t iSliceNum = GetInitialSliceNum (pDq->iMbWidth, pDq->iMbHeight, &pDlp->sSliceArgument);
             if (pDlp->sSliceArgument.uiSliceMode == SM_SIZELIMITED_SLICE && pCtx->iActiveThreadsNum == 1) {
-              if (iSliceNum < pDq->pSliceEncCtx->iMaxSliceNumConstraint) {
-                iSliceNum = pDq->pSliceEncCtx->iMaxSliceNumConstraint;
+              if (iSliceNum < pDq->sSliceEncCtx.iMaxSliceNumConstraint) {
+                iSliceNum = pDq->sSliceEncCtx.iMaxSliceNumConstraint;
               }
             }
             if (iSliceNum < 1)
@@ -2125,6 +2120,11 @@
             pDq->pFeatureSearchPreparation = NULL;
           }
 
+          SSliceCtx* pSliceCtx = &pDq->sSliceEncCtx;
+          if (NULL != pSliceCtx) {
+            UninitSlicePEncCtx (pSliceCtx, pMa);
+          }
+
           pMa->WelsFree (pDq, "pDq");
           pDq = NULL;
           pCtx->ppDqLayerList[ilayer] = NULL;
@@ -2158,19 +2158,6 @@
       pCtx->ppRefPicListExt = NULL;
     }
 
-    // pSlice context list
-    if (NULL != pCtx->pSliceCtxList && pParam != NULL) {
-      ilayer = 0;
-      while (ilayer < pParam->iSpatialLayerNum) {
-        SSliceCtx* pSliceCtx = &pCtx->pSliceCtxList[ilayer];
-        if (NULL != pSliceCtx)
-          UninitSlicePEncCtx (pSliceCtx, pMa);
-        ++ ilayer;
-      }
-      pMa->WelsFree (pCtx->pSliceCtxList, "pSliceCtxList");
-      pCtx->pSliceCtxList = NULL;
-    }
-
     // VAA
     if (NULL != pCtx->pVaa) {
       if (pCtx->pSvcParam->bEnableAdaptiveQuant) { //free mem
@@ -2758,7 +2745,7 @@
 void WelsInitCurrentQBLayerMltslc (sWelsEncCtx* pCtx) {
   //pData init
   SDqLayer*  pCurDq    = pCtx->pCurDqLayer;
-  SSliceCtx* pSliceCtx = (pCurDq->pSliceEncCtx);
+  SSliceCtx* pSliceCtx = &(pCurDq->sSliceEncCtx);
 
   //mb_neighbor
   DynslcUpdateMbNeighbourInfoListForAllSlices (pSliceCtx, pCurDq->sMbDataP);
@@ -2765,7 +2752,7 @@
 }
 
 void UpdateSlicepEncCtxWithPartition (SDqLayer* pCurDq, int32_t iPartitionNum) {
-  SSliceCtx* pSliceCtx                  = pCurDq->pSliceEncCtx;
+  SSliceCtx* pSliceCtx                  = &pCurDq->sSliceEncCtx;
   const int32_t kiMbNumInFrame          = pSliceCtx->iMbNumInFrame;
   int32_t iCountMbNumPerPartition       = kiMbNumInFrame;
   int32_t iAssignableMbLeft             = kiMbNumInFrame;
@@ -2799,7 +2786,7 @@
 
 void WelsInitCurrentDlayerMltslc (sWelsEncCtx* pCtx, int32_t iPartitionNum) {
   SDqLayer* pCurDq      = pCtx->pCurDqLayer;
-  SSliceCtx* pSliceCtx  = pCurDq->pSliceEncCtx;
+  SSliceCtx* pSliceCtx  = &pCurDq->sSliceEncCtx;
 
   UpdateSlicepEncCtxWithPartition (pCurDq, iPartitionNum);
 
@@ -2877,7 +2864,7 @@
   if (fDlp->sSliceArgument.uiSliceMode == SM_SIZELIMITED_SLICE) // need get extra slices for update
     iSliceCount = GetInitialSliceNum (pCurDq->iMbWidth, pCurDq->iMbHeight, &fDlp->sSliceArgument);
   else
-    iSliceCount = GetCurrentSliceNum (pCurDq->pSliceEncCtx);
+    iSliceCount = GetCurrentSliceNum (&pCurDq->sSliceEncCtx);
   assert (iSliceCount > 0);
 
   int32_t iCurPpsId = pDqIdc->iPpsId;
@@ -3140,7 +3127,7 @@
  */
 static inline void PrefetchReferencePicture (sWelsEncCtx* pCtx, const EVideoFrameType keFrameType) {
   SSlice* pSliceBase = &pCtx->pCurDqLayer->sLayerInfo.pSliceInLayer[0];
-  const int32_t kiSliceCount = GetCurrentSliceNum (pCtx->pCurDqLayer->pSliceEncCtx);
+  const int32_t kiSliceCount = GetCurrentSliceNum (&pCtx->pCurDqLayer->sSliceEncCtx);
   int32_t iIdx = 0;
   uint8_t uiRefIdx = -1;
 
@@ -4019,7 +4006,7 @@
     }
     // for dynamic slicing single threading..
     else if ((SM_SIZELIMITED_SLICE == pParam->sSliceArgument.uiSliceMode) && (pSvcParam->iMultipleThreadIdc <= 1)) {
-      const int32_t kiLastMbInFrame = pCtx->pCurDqLayer->pSliceEncCtx->iMbNumInFrame;
+      const int32_t kiLastMbInFrame = pCtx->pCurDqLayer->sSliceEncCtx.iMbNumInFrame;
       pCtx->iEncoderError = WelsCodeOnePicPartition (pCtx, pFbi, pLayerBsInfo, &iNalIdxInLayer, &iLayerSize, 0,
                             kiLastMbInFrame, 0);
       WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
@@ -4028,7 +4015,7 @@
       int32_t iRet = 0;
       // THREAD_FULLY_FIRE_MODE/THREAD_PICK_UP_MODE for any mode of non-SM_SIZELIMITED_SLICE
       if ((SM_SIZELIMITED_SLICE != pParam->sSliceArgument.uiSliceMode) && (pSvcParam->iMultipleThreadIdc > 1)) {
-        iSliceCount = GetCurrentSliceNum (pCtx->pCurDqLayer->pSliceEncCtx);
+        iSliceCount = GetCurrentSliceNum (&pCtx->pCurDqLayer->sSliceEncCtx);
         if (iLayerNum + 1 >= MAX_LAYER_NUM_OF_FRAME) { // check available layer_bs_info for further writing as followed
           WelsLog (pLogCtx, WELS_LOG_ERROR,
                    "WelsEncoderEncodeExt(), iLayerNum(%d) overflow(max:%d) at iDid= %d uiSliceMode= %d, iSliceCount= %d!",
@@ -4061,7 +4048,7 @@
         iRet = FiredSliceThreads (pCtx, &pCtx->pSliceThreading->pThreadPEncCtx[0],
                                   &pCtx->pSliceThreading->pReadySliceCodingEvent[0],
                                   &pCtx->pSliceThreading->pThreadMasterEvent[0],
-                                  pFbi, kiPartitionCnt, pCtx->pCurDqLayer->pSliceEncCtx, true);
+                                  pFbi, kiPartitionCnt, &pCtx->pCurDqLayer->sSliceEncCtx, true);
         if (iRet) {
           WelsLog (pLogCtx, WELS_LOG_ERROR,
                    "[MT] WelsEncoderEncodeExt(), FiredSliceThreads return(%d) failed and exit encoding frame, iCountThreadsNum= %d, iSliceCount= %d, uiSliceMode= %d, iMultipleThreadIdc= %d!!",
@@ -4078,7 +4065,7 @@
         const bool bNeedPrefix = pCtx->bNeedPrefixNalFlag;
         int32_t iSliceIdx = 0;
 
-        iSliceCount = GetCurrentSliceNum (pCtx->pCurDqLayer->pSliceEncCtx);
+        iSliceCount = GetCurrentSliceNum (&pCtx->pCurDqLayer->sSliceEncCtx);
         while (iSliceIdx < iSliceCount) {
           int32_t iSliceSize    = 0;
           int32_t iPayloadSize  = 0;
@@ -4314,7 +4301,7 @@
         && pSvcParam->bUseLoadBalancing
         && pSvcParam->iMultipleThreadIdc > 1 &&
         pSvcParam->iMultipleThreadIdc >= pParam->sSliceArgument.uiSliceNum) {
-      CalcSliceComplexRatio (pCtx->pSliceThreading->pSliceComplexRatio[iCurDid], pCtx->pCurDqLayer->pSliceEncCtx,
+      CalcSliceComplexRatio (pCtx->pSliceThreading->pSliceComplexRatio[iCurDid], &pCtx->pCurDqLayer->sSliceEncCtx,
                              pCtx->pSliceThreading->pSliceConsumeTime[iCurDid]);
 #if defined(MT_DEBUG)
       TrackSliceComplexities (pCtx, iCurDid);
@@ -4740,7 +4727,7 @@
   SDqLayer* pCurLayer = pCtx->pCurDqLayer;
 
   int32_t iCountNals = pCtx->pOut->iCountNals;
-  int32_t iMaxSliceNumOld = pCurLayer->pSliceEncCtx->iMaxSliceNumConstraint;
+  int32_t iMaxSliceNumOld = pCurLayer->sSliceEncCtx.iMaxSliceNumConstraint;
   int32_t iMaxSliceNum = iMaxSliceNumOld;
   iCountNals += iMaxSliceNum * (pCtx->pSvcParam->iSpatialLayerNum + pCtx->bNeedPrefixNalFlag);
   iMaxSliceNum *= SLICE_NUM_EXPAND_COEF;
@@ -4820,9 +4807,9 @@
     return ENC_RETURN_MEMALLOCERR;
   }
   memset (pFirstMbInSlice, 0, sizeof (int32_t) * iMaxSliceNum);
-  memcpy (pFirstMbInSlice, pCurLayer->pSliceEncCtx->pFirstMbInSlice, sizeof (int32_t) * iMaxSliceNumOld);
-  pMA->WelsFree (pCurLayer->pSliceEncCtx->pFirstMbInSlice, "pSliceSeg->pFirstMbInSlice");
-  pCurLayer->pSliceEncCtx->pFirstMbInSlice = pFirstMbInSlice;
+  memcpy (pFirstMbInSlice, pCurLayer->sSliceEncCtx.pFirstMbInSlice, sizeof (int32_t) * iMaxSliceNumOld);
+  pMA->WelsFree (pCurLayer->sSliceEncCtx.pFirstMbInSlice, "pSliceSeg->pFirstMbInSlice");
+  pCurLayer->sSliceEncCtx.pFirstMbInSlice = pFirstMbInSlice;
 
   int32_t* pCountMbNumInSlice = (int32_t*)pMA->WelsMalloc (iMaxSliceNum * sizeof (int32_t),
                                 "pSliceSeg->pCountMbNumInSlice");
@@ -4831,14 +4818,14 @@
              "CWelsH264SVCEncoder::DynSliceRealloc: realloc pCountMbNumInSlice not successful");
     return ENC_RETURN_MEMALLOCERR;
   }
-  memcpy (pCountMbNumInSlice, pCurLayer->pSliceEncCtx->pCountMbNumInSlice, sizeof (int32_t) * iMaxSliceNumOld);
+  memcpy (pCountMbNumInSlice, pCurLayer->sSliceEncCtx.pCountMbNumInSlice, sizeof (int32_t) * iMaxSliceNumOld);
   uiSliceIdx = iMaxSliceNumOld;
   while (uiSliceIdx < iMaxSliceNum) {
-    pCountMbNumInSlice[uiSliceIdx] = pCurLayer->pSliceEncCtx->iMbNumInFrame;
+    pCountMbNumInSlice[uiSliceIdx] = pCurLayer->sSliceEncCtx.iMbNumInFrame;
     uiSliceIdx++;
   }
-  pMA->WelsFree (pCurLayer->pSliceEncCtx->pCountMbNumInSlice, "pSliceSeg->pCountMbNumInSlice");
-  pCurLayer->pSliceEncCtx->pCountMbNumInSlice = pCountMbNumInSlice;
+  pMA->WelsFree (pCurLayer->sSliceEncCtx.pCountMbNumInSlice, "pSliceSeg->pCountMbNumInSlice");
+  pCurLayer->sSliceEncCtx.pCountMbNumInSlice = pCountMbNumInSlice;
 
   uint32_t* pSliceConsumeTime = (uint32_t*)pMA->WelsMalloc (iMaxSliceNum * sizeof (uint32_t),
                                                           "pSliceSeg->pSliceConsumeTime");
@@ -4847,9 +4834,9 @@
              "CWelsH264SVCEncoder::DynSliceRealloc: realloc pSliceConsumeTime not successful");
     return ENC_RETURN_MEMALLOCERR;
   }
-  memcpy (pSliceConsumeTime, pCurLayer->pSliceEncCtx->pSliceConsumeTime, sizeof (int32_t) * iMaxSliceNumOld);
-  pMA->WelsFree (pCurLayer->pSliceEncCtx->pSliceConsumeTime, "pSliceSeg->pSliceConsumeTime");
-  pCurLayer->pSliceEncCtx->pSliceConsumeTime = pSliceConsumeTime;
+  memcpy (pSliceConsumeTime, pCurLayer->sSliceEncCtx.pSliceConsumeTime, sizeof (int32_t) * iMaxSliceNumOld);
+  pMA->WelsFree (pCurLayer->sSliceEncCtx.pSliceConsumeTime, "pSliceSeg->pSliceConsumeTime");
+  pCurLayer->sSliceEncCtx.pSliceConsumeTime = pSliceConsumeTime;
 
   //deal with rate control variables
   const int32_t kiCurDid = pCtx->uiDependencyId;
@@ -4869,7 +4856,7 @@
     pSORC->iCalculatedQpSlice = pCtx->iGlobalQp;
     pSORC->iTotalQpSlice    = 0;
     pSORC->iTotalMbSlice    = 0;
-    pSORC->iTargetBitsSlice = WELS_DIV_ROUND (kiBitsPerMb * pCurLayer->pSliceEncCtx->pCountMbNumInSlice[uiSliceIdx],
+    pSORC->iTargetBitsSlice = WELS_DIV_ROUND (kiBitsPerMb * pCurLayer->sSliceEncCtx.pCountMbNumInSlice[uiSliceIdx],
                               INT_MULTIPLY);
     pSORC->iFrameBitsSlice  = 0;
     pSORC->iGomBitsSlice    = 0;
@@ -4881,7 +4868,7 @@
 
   if (pCtx->iMaxSliceCount < iMaxSliceNum)
     pCtx->iMaxSliceCount = iMaxSliceNum;
-  pCurLayer->pSliceEncCtx->iMaxSliceNumConstraint = iMaxSliceNum;
+  pCurLayer->sSliceEncCtx.iMaxSliceNumConstraint = iMaxSliceNum;
   return ENC_RETURN_SUCCESS;
 }
 
@@ -4896,7 +4883,7 @@
                                 ) {
 
   SDqLayer* pCurLayer                   = pCtx->pCurDqLayer;
-  SSliceCtx* pSliceCtx                  = pCurLayer->pSliceEncCtx;
+  SSliceCtx* pSliceCtx                  = &pCurLayer->sSliceEncCtx;
   int32_t iNalIdxInLayer                = *pNalIdxInLayer;
   int32_t iSliceIdx                     = iStartSliceIdx;
   const int32_t kiSliceStep             = pCtx->iActiveThreadsNum;
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -114,7 +114,7 @@
   bool bMultiSliceMode = false;
   int32_t iGomRowMode0 = 1, iGomRowMode1 = 1;
   for (j = 0; j < pEncCtx->pSvcParam->iSpatialLayerNum; j++) {
-    SSliceCtx* pSliceCtx = &pEncCtx->pSliceCtxList[j];
+    SSliceCtx* pSliceCtx = &pEncCtx->ppDqLayerList[j]->sSliceEncCtx;
     pWelsSvcRc  = &pEncCtx->pWelsSvcRc[j];
     pDLayerParam = &pEncCtx->pSvcParam->sSpatialLayers[j];
     iMbWidth     = (pDLayerParam->iVideoWidth >> 4);
@@ -511,7 +511,7 @@
 }
 
 void RcInitSliceInformation (sWelsEncCtx* pEncCtx) {
-  SSliceCtx* pCurSliceCtx       = pEncCtx->pCurDqLayer->pSliceEncCtx;
+  SSliceCtx* pCurSliceCtx       = &pEncCtx->pCurDqLayer->sSliceEncCtx;
   SWelsSvcRc* pWelsSvcRc        = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
   SRCSlicing* pSOverRc          = &pWelsSvcRc->pSlicingOverRc[0];
   const int32_t kiSliceNum      = pWelsSvcRc->iSliceNum;
@@ -922,7 +922,7 @@
 void RcUpdatePictureQpBits (sWelsEncCtx* pEncCtx, int32_t iCodedBits) {
   SWelsSvcRc* pWelsSvcRc = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
   SRCSlicing* pSOverRc = &pWelsSvcRc->pSlicingOverRc[0];
-  SSliceCtx* pCurSliceCtx = pEncCtx->pCurDqLayer->pSliceEncCtx;
+  SSliceCtx* pCurSliceCtx = &pEncCtx->pCurDqLayer->sSliceEncCtx;
   int32_t iTotalQp = 0, iTotalMb = 0;
   int32_t i;
 
--- a/codec/encoder/core/src/ref_list_mgr_svc.cpp
+++ b/codec/encoder/core/src/ref_list_mgr_svc.cpp
@@ -479,7 +479,7 @@
 }
 void WelsMarkPic (sWelsEncCtx* pCtx) {
   SLTRState* pLtr               = &pCtx->pLtr[pCtx->uiDependencyId];
-  const int32_t kiCountSliceNum = GetCurrentSliceNum (pCtx->pCurDqLayer->pSliceEncCtx);
+  const int32_t kiCountSliceNum = GetCurrentSliceNum (&pCtx->pCurDqLayer->sSliceEncCtx);
   SSlice* pSliceList            = NULL;
 
   if (pCtx->pSvcParam->bEnableLongTermReference && pLtr->bLTRMarkEnable && pCtx->uiTemporalId == 0) {
@@ -641,7 +641,7 @@
 
 void WelsUpdateSliceHeaderSyntax(sWelsEncCtx* pCtx,  const int32_t iAbsDiffPicNumMinus1,
                                  SSlice* pSliceList, const int32_t uiFrameType) {
-  const int32_t kiCountSliceNum = GetCurrentSliceNum(pCtx->pCurDqLayer->pSliceEncCtx);
+  const int32_t kiCountSliceNum = GetCurrentSliceNum(&pCtx->pCurDqLayer->sSliceEncCtx);
   SLTRState* pLtr               = &pCtx->pLtr[pCtx->uiDependencyId];
   int32_t iIdx = 0;
 
@@ -973,7 +973,7 @@
     }
   }
 
-  const int32_t iSliceNum = GetCurrentSliceNum(pCtx->pCurDqLayer->pSliceEncCtx);
+  const int32_t iSliceNum = GetCurrentSliceNum(&pCtx->pCurDqLayer->sSliceEncCtx);
 
   if (pCtx->iActiveThreadsNum > 1) {
     // to do: will replace with thread based buffer later
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -80,7 +80,7 @@
 void UpdateMbListNeighborParallel (SDqLayer* pCurDq,
                                    SMB* pMbList,
                                    const int32_t uiSliceIdc) {
-  SSliceCtx* pSliceCtx           = pCurDq->pSliceEncCtx;
+  SSliceCtx* pSliceCtx           = &pCurDq->sSliceEncCtx;
   const uint16_t* kpMbMap        = pSliceCtx->pOverallMbMap;
   const int32_t kiMbWidth        = pSliceCtx->iMbWidth;
   int32_t iIdx                   = pSliceCtx->pFirstMbInSlice[uiSliceIdc];
@@ -203,7 +203,7 @@
                            SDqLayer* pCurDqLayer,
                            void* pComplexRatio,
                            int32_t iCurDid) {
-  SSliceCtx* pSliceCtx  = pCurDqLayer->pSliceEncCtx;
+  SSliceCtx* pSliceCtx  = &pCurDqLayer->sSliceEncCtx;
   const int32_t kiCountSliceNum = pSliceCtx->iSliceNumInFrame;
   const int32_t kiCountNumMb    = pSliceCtx->iMbNumInFrame;
   int32_t iMinimalMbNum         =
@@ -818,7 +818,7 @@
                         "[MT] CodingSliceThreadProc(), coding_idx %d, uiSliceIdx %d, pSliceConsumeTime %d, iSliceSize %d, pFirstMbInSlice %d, count_num_mb_in_slice %d",
                         pEncPEncCtx->iCodingIndex, iSliceIdx,
                         pEncPEncCtx->pSliceThreading->pSliceConsumeTime[pEncPEncCtx->uiDependencyId][iSliceIdx], iSliceSize,
-                        pCurDq->pSliceEncCtx->pFirstMbInSlice[iSliceIdx], pCurDq->pSliceEncCtx->pCountMbNumInSlice[iSliceIdx]);
+                        pCurDq->sSliceEncCtx.pFirstMbInSlice[iSliceIdx], pCurDq->sSliceEncCtx.pCountMbNumInSlice[iSliceIdx]);
         }
 
 #if defined(SLICE_INFO_OUTPUT)
@@ -840,7 +840,7 @@
         WelsEventSignal (
           &pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent);
       } else { // for SM_SIZELIMITED_SLICE parallelization
-        SSliceCtx* pSliceCtx                    = pCurDq->pSliceEncCtx;
+        SSliceCtx* pSliceCtx                    = &pCurDq->sSliceEncCtx;
         const int32_t kiPartitionId             = iThreadIdx;
         const int32_t kiSliceIdxStep            = pEncPEncCtx->iActiveThreadsNum;
         const int32_t kiFirstMbInPartition      = pPrivateData->iStartMbIndex;  // inclusive
@@ -938,7 +938,7 @@
 
           MT_TRACE_LOG (pEncPEncCtx, 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->pSliceEncCtx->pCountMbNumInSlice[iSliceIdx],
+                        pEncPEncCtx->iCodingIndex, kiPartitionId, iSliceIdx, iSliceSize, pCurDq->sSliceEncCtx.pCountMbNumInSlice[iSliceIdx],
                         kiEndMbInPartition, kiPartitionId, pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]);
 
           iAnyMbLeftInPartition = kiEndMbInPartition - (1 + pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]);
@@ -1062,10 +1062,10 @@
 #endif//MT_DEBUG
 
   pCtx->pCurDqLayer = pCurDq;
-  memcpy ((pCtx->pSliceThreading->pSliceConsumeTime[0]), (pCurDq->pSliceEncCtx->pSliceConsumeTime),
-          pCurDq->pSliceEncCtx->iSliceNumInFrame * sizeof (uint32_t));
+  memcpy ((pCtx->pSliceThreading->pSliceConsumeTime[0]), (pCurDq->sSliceEncCtx.pSliceConsumeTime),
+          pCurDq->sSliceEncCtx.iSliceNumInFrame * sizeof (uint32_t));
   // do not need adjust due to not different at both slices of consumed time
-  iNeedAdj = NeedDynamicAdjust (pCtx->pSliceThreading->pSliceConsumeTime[0], pCurDq->pSliceEncCtx->iSliceNumInFrame);
+  iNeedAdj = NeedDynamicAdjust (pCtx->pSliceThreading->pSliceConsumeTime[0], pCurDq->sSliceEncCtx.iSliceNumInFrame);
   if (iNeedAdj)
     DynamicAdjustSlicing (pCtx,
                           pCurDq,
@@ -1095,13 +1095,13 @@
                                      && (pCtx->pSvcParam->sSpatialLayers[iCurDid - 1].sSliceArgument.uiSliceMode == SM_FIXEDSLCNUM_SLICE
                                          && pCtx->pSvcParam->iMultipleThreadIdc >= pCtx->pSvcParam->sSpatialLayers[iCurDid -
                                              1].sSliceArgument.uiSliceNum);
-  memcpy ((pCtx->pSliceThreading->pSliceConsumeTime[iCurDid]), (pCtx->pCurDqLayer->pSliceEncCtx->pSliceConsumeTime),
-          pCtx->pCurDqLayer->pSliceEncCtx->iSliceNumInFrame * sizeof (uint32_t));
+  memcpy ((pCtx->pSliceThreading->pSliceConsumeTime[iCurDid]), (pCtx->pCurDqLayer->sSliceEncCtx.pSliceConsumeTime),
+          pCtx->pCurDqLayer->sSliceEncCtx.iSliceNumInFrame * sizeof (uint32_t));
 
   if (kbModelingFromSpatial) { // using spatial base layer for complexity estimation
     // do not need adjust due to not different at both slices of consumed time
     iNeedAdj = NeedDynamicAdjust (pCtx->pSliceThreading->pSliceConsumeTime[iCurDid - 1],
-                                  pCtx->pCurDqLayer->pSliceEncCtx->iSliceNumInFrame);
+                                  pCtx->pCurDqLayer->sSliceEncCtx.iSliceNumInFrame);
     if (iNeedAdj)
       DynamicAdjustSlicing (pCtx,
                             pCtx->pCurDqLayer,
@@ -1111,7 +1111,7 @@
   } else { // use temporal layer for complexity estimation
     // do not need adjust due to not different at both slices of consumed time
     iNeedAdj = NeedDynamicAdjust (pCtx->pSliceThreading->pSliceConsumeTime[iCurDid],
-                                  pCtx->pCurDqLayer->pSliceEncCtx->iSliceNumInFrame);
+                                  pCtx->pCurDqLayer->sSliceEncCtx.iSliceNumInFrame);
     if (iNeedAdj)
       DynamicAdjustSlicing (pCtx,
                             pCtx->pCurDqLayer,
@@ -1136,7 +1136,7 @@
 
 #if defined(MT_DEBUG)
 void TrackSliceComplexities (sWelsEncCtx* pCtx, const int32_t iCurDid) {
-  const int32_t kiCountSliceNum = pCtx->pCurDqLayer->pSliceEncCtx->iSliceNumInFrame;
+  const int32_t kiCountSliceNum = pCtx->pCurDqLayer->sSliceEncCtx.iSliceNumInFrame;
   if (kiCountSliceNum > 0) {
     int32_t iSliceIdx = 0;
     do {
@@ -1162,7 +1162,7 @@
     SSpatialLayerInternal* pDlp = &pPara->sDependencyLayers[kiDid];
     SSliceConfig* pSliceArgument          = &pDlp->sSliceArgument;
     SDqLayer* pCurDq            = pCtx->ppDqLayerList[kiDid];
-    SSliceCtx* pSliceCtx = pCurDq->pSliceEncCtx;
+    SSliceCtx* pSliceCtx = &pCurDq->sSliceEncCtx;
     const uint32_t kuiCountSliceNum = pSliceCtx->iSliceNumInFrame;
     if (pCtx->pSliceThreading) {
       if (pCtx->pSliceThreading->pFSliceDiff
--- a/codec/encoder/core/src/svc_encode_slice.cpp
+++ b/codec/encoder/core/src/svc_encode_slice.cpp
@@ -94,7 +94,7 @@
 
   pCurSliceExt->bStoreRefBasePicFlag = false;
 
-  pCurSliceHeader->iFirstMbInSlice = WelsGetFirstMbOfSlice (pCurLayer->pSliceEncCtx, pSlice->uiSliceIdx);
+  pCurSliceHeader->iFirstMbInSlice = WelsGetFirstMbOfSlice (&pCurLayer->sSliceEncCtx, pSlice->uiSliceIdx);
 
   pCurSliceHeader->iFrameNum      = pEncCtx->iFrameNum;
   pCurSliceHeader->uiIdrPicId     = pEncCtx->uiIdrPicId;
@@ -483,7 +483,7 @@
 //second. lower than highest Dependency Layer, and for every Dependency Layer with one quality layer(single layer)
 int32_t WelsISliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + encoding
   SDqLayer* pCurLayer           = pEncCtx->pCurDqLayer;
-  SSliceCtx* pSliceCtx          = pCurLayer->pSliceEncCtx;
+  SSliceCtx* pSliceCtx          = &pCurLayer->sSliceEncCtx;
   SMbCache* pMbCache            = &pSlice->sMbCacheInfo;
   SSliceHeaderExt* pSliceHdExt  = &pSlice->sSliceHeaderExt;
   SMB* pMbList                  = pCurLayer->sMbDataP;
@@ -546,7 +546,7 @@
 int32_t WelsISliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + encoding
   SBitStringAux* pBs            = pSlice->pSliceBsa;
   SDqLayer* pCurLayer           = pEncCtx->pCurDqLayer;
-  SSliceCtx* pSliceCtx          = pCurLayer->pSliceEncCtx;
+  SSliceCtx* pSliceCtx          = &pCurLayer->sSliceEncCtx;
   SMbCache* pMbCache            = &pSlice->sMbCacheInfo;
   SSliceHeaderExt* pSliceHdExt  = &pSlice->sSliceHeaderExt;
   SMB* pMbList                  = pCurLayer->sMbDataP;
@@ -942,7 +942,7 @@
   SWelsMD* pMd          = (SWelsMD*)pWelsMd;
   SBitStringAux* pBs    = pSlice->pSliceBsa;
   SDqLayer* pCurLayer   = pEncCtx->pCurDqLayer;
-  SSliceCtx* pSliceCtx  = pCurLayer->pSliceEncCtx;
+  SSliceCtx* pSliceCtx  = &pCurLayer->sSliceEncCtx;
   SMbCache* pMbCache    = &pSlice->sMbCacheInfo;
   SMB* pMbList          = pCurLayer->sMbDataP;
   SMB* pCurMb           = NULL;
@@ -1033,7 +1033,7 @@
   SWelsMD* pMd          = (SWelsMD*)pWelsMd;
   SBitStringAux* pBs    = pSlice->pSliceBsa;
   SDqLayer* pCurLayer   = pEncCtx->pCurDqLayer;
-  SSliceCtx* pSliceCtx  = pCurLayer->pSliceEncCtx;
+  SSliceCtx* pSliceCtx  = &pCurLayer->sSliceEncCtx;
   SMbCache* pMbCache    = &pSlice->sMbCacheInfo;
   SMB* pMbList          = pCurLayer->sMbDataP;
   SMB* pCurMb           = NULL;
--- a/codec/encoder/core/src/svc_motion_estimate.cpp
+++ b/codec/encoder/core/src/svc_motion_estimate.cpp
@@ -1016,7 +1016,7 @@
 //switch related
 static uint32_t CountFMECostDown (const SDqLayer* pCurLayer) {
   uint32_t uiCostDownSum      = 0;
-  const int32_t kiSliceCount  = GetCurrentSliceNum (pCurLayer->pSliceEncCtx);
+  const int32_t kiSliceCount  = GetCurrentSliceNum (&pCurLayer->sSliceEncCtx);
   if (kiSliceCount >= 1) {
     int32_t iSliceIndex  = 0;
     SSlice* pSlice    = &pCurLayer->sLayerInfo.pSliceInLayer[iSliceIndex];
--- a/codec/encoder/core/src/wels_task_encoder.cpp
+++ b/codec/encoder/core/src/wels_task_encoder.cpp
@@ -216,15 +216,15 @@
 void CWelsLoadBalancingSlicingEncodingTask::FinishTask() {
   CWelsSliceEncodingTask::FinishTask();
 
-  m_pCtx->pCurDqLayer->pSliceEncCtx->pSliceConsumeTime[m_iSliceIdx] = (uint32_t) (WelsTime() - m_iSliceStart);
+  m_pCtx->pCurDqLayer->sSliceEncCtx.pSliceConsumeTime[m_iSliceIdx] = (uint32_t) (WelsTime() - m_iSliceStart);
   WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG,
            "[MT] CWelsLoadBalancingSlicingEncodingTask()FinishTask, coding_idx %d, um_iSliceIdx %d, pSliceConsumeTime %d, iSliceSize %d, pFirstMbInSlice %d, count_num_mb_in_slice %d",
            m_pCtx->iCodingIndex,
            m_iSliceIdx,
-           m_pCtx->pCurDqLayer->pSliceEncCtx->pSliceConsumeTime[m_iSliceIdx],
+           m_pCtx->pCurDqLayer->sSliceEncCtx.pSliceConsumeTime[m_iSliceIdx],
            m_iSliceSize,
-           m_pCtx->pCurDqLayer->pSliceEncCtx->pFirstMbInSlice[m_iSliceIdx],
-           m_pCtx->pCurDqLayer->pSliceEncCtx->pCountMbNumInSlice[m_iSliceIdx]);
+           m_pCtx->pCurDqLayer->sSliceEncCtx.pFirstMbInSlice[m_iSliceIdx],
+           m_pCtx->pCurDqLayer->sSliceEncCtx.pCountMbNumInSlice[m_iSliceIdx]);
 }