shithub: openh264

Download patch

ref: 2d3071e37cd17d44b05abcac9abb577b91d5349a
parent: 6f15550b9e30f0acd813b1fd551f027946384475
parent: 9ef07c5b99c289480d2402984a865a68dc54eac6
author: ruil2 <ruil2@cisco.com>
date: Fri Nov 20 09:35:00 EST 2015

Merge pull request #2262 from shihuade/MultiThread_V4.2_SSliceCtx_PFirstMBInSlice_Pull

remove pFirstMbInSlice in SSliceCtx

--- a/codec/encoder/core/inc/svc_enc_macroblock.h
+++ b/codec/encoder/core/inc/svc_enc_macroblock.h
@@ -69,7 +69,7 @@
 
 uint8_t         uiLumaQp;       // uiLumaQp: pPps->iInitialQp + sSliceHeader->delta_qp + mb->dquant.
 uint8_t         uiChromaQp;
-uint16_t        uiSliceIdc;     // 2^16=65536 > MaxFS(36864) of level 5.1; AVC: pFirstMbInSlice?; SVC: (pFirstMbInSlice << 7) | ((uiDependencyId << 4) | uiQualityId);
+uint16_t        uiSliceIdc;     // 2^16=65536 > MaxFS(36864) of level 5.1; AVC: iFirstMbInSlice?; SVC: (iFirstMbInSlice << 7) | ((uiDependencyId << 4) | uiQualityId);
 uint32_t        uiChromPredMode;
 int32_t         iLumaDQp;
 SMVUnitXY       sMvd[MB_BLOCK4x4_NUM]; //only for CABAC writing; storage structure the same as sMv, in 4x4 scan order.
--- a/codec/encoder/core/inc/svc_enc_slice_segment.h
+++ b/codec/encoder/core/inc/svc_enc_slice_segment.h
@@ -86,7 +86,6 @@
 int32_t                 iSliceNumInFrame;       /* count number of slices in frame; */
 int32_t                 iMbNumInFrame;          /* count number of MBs in frame */
 uint16_t*               pOverallMbMap;          /* overall MB map in frame, store virtual slice idc; */
-int32_t*                pFirstMbInSlice;        /* first MB address top-left based in every slice respectively; */
 int32_t*                pCountMbNumInSlice;     /* count number of MBs in every slice respectively; */
 uint32_t                uiSliceSizeConstraint;  /* in byte */
 int32_t                 iMaxSliceNumConstraint; /* maximal number of slices constraint */
@@ -152,12 +151,12 @@
 /*!
  * \brief   Get first mb in slice/slice_group: uiSliceIdc (apply in Single/multiple slices and FMO)
  *
- * \param   pSliceCtx       SSlice context
+ * \param   pSliceInLayer   slice list in current layer
  * \param   kiSliceIdc      slice idc
  *
  * \return  first_mb - successful; -1 - failed;
  */
-int32_t WelsGetFirstMbOfSlice (SSliceCtx* pSliceCtx, const int32_t kiSliceIdc);
+int32_t WelsGetFirstMbOfSlice (SSlice* pSliceInLayer, 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/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -2750,6 +2750,7 @@
 
 void UpdateSlicepEncCtxWithPartition (SDqLayer* pCurDq, int32_t iPartitionNum) {
   SSliceCtx* pSliceCtx                  = &pCurDq->sSliceEncCtx;
+  SSlice* pSliceInLayer                 = pCurDq->sLayerInfo.pSliceInLayer;
   const int32_t kiMbNumInFrame          = pSliceCtx->iMbNumInFrame;
   int32_t iCountMbNumPerPartition       = kiMbNumInFrame;
   int32_t iAssignableMbLeft             = kiMbNumInFrame;
@@ -2769,7 +2770,7 @@
     } else {
       pSliceCtx->pCountMbNumInSlice[i] = iCountMbNumPerPartition;
     }
-    pSliceCtx->pFirstMbInSlice[i] = iFirstMbIdx;
+    pSliceInLayer[i].sSliceHeaderExt.sSliceHeader.iFirstMbInSlice = iFirstMbIdx;
 
     WelsSetMemMultiplebytes_c (pSliceCtx->pOverallMbMap + iFirstMbIdx, i,
                                pSliceCtx->pCountMbNumInSlice[i], sizeof (uint16_t));
@@ -4797,17 +4798,6 @@
   }
   pMA->WelsFree (pCurLayer->sLayerInfo.pSliceInLayer, "Slice");
   pCurLayer->sLayerInfo.pSliceInLayer = pSlice;
-
-  int32_t* pFirstMbInSlice = (int32_t*)pMA->WelsMalloc (iMaxSliceNum * sizeof (int32_t), "pSliceSeg->pFirstMbInSlice");
-  if (NULL == pFirstMbInSlice) {
-    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::DynSliceRealloc: pFirstMbInSlice is NULL");
-    return ENC_RETURN_MEMALLOCERR;
-  }
-  memset (pFirstMbInSlice, 0, sizeof (int32_t) * iMaxSliceNum);
-  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");
   if (NULL == pCountMbNumInSlice) {
@@ -4881,6 +4871,8 @@
 
   SDqLayer* pCurLayer                   = pCtx->pCurDqLayer;
   SSliceCtx* pSliceCtx                  = &pCurLayer->sSliceEncCtx;
+  SSlice* pSliceInLayer                 = pCurLayer->sLayerInfo.pSliceInLayer;
+  SSlice* pStartSlice                   = &pSliceInLayer[iStartSliceIdx];
   int32_t iNalIdxInLayer                = *pNalIdxInLayer;
   int32_t iSliceIdx                     = iStartSliceIdx;
   const int32_t kiSliceStep             = pCtx->iActiveThreadsNum;
@@ -4895,7 +4887,7 @@
 
   //init
   {
-    pSliceCtx->pFirstMbInSlice[iSliceIdx]               = iFirstMbInPartition;
+    pStartSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice = iFirstMbInPartition;
     pCurLayer->pNumSliceCodedOfPartition[kiPartitionId] = 1;    // one slice per partition intialized, dynamic slicing inside
     pCurLayer->pLastMbIdxOfPartition[kiPartitionId]     = iEndMbInPartition - 1;
   }
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -512,6 +512,7 @@
 
 void RcInitSliceInformation (sWelsEncCtx* pEncCtx) {
   SSliceCtx* pCurSliceCtx       = &pEncCtx->pCurDqLayer->sSliceEncCtx;
+  SSlice* pSliceInLayer         = pEncCtx->pCurDqLayer->sLayerInfo.pSliceInLayer;
   SWelsSvcRc* pWelsSvcRc        = &pEncCtx->pWelsSvcRc[pEncCtx->uiDependencyId];
   SRCSlicing* pSOverRc          = &pWelsSvcRc->pSlicingOverRc[0];
   const int32_t kiSliceNum      = pWelsSvcRc->iSliceNum;
@@ -520,7 +521,7 @@
 
   for (int32_t i = 0; i < kiSliceNum; i++) {
     pSOverRc->iStartMbSlice     =
-      pSOverRc->iEndMbSlice     = pCurSliceCtx->pFirstMbInSlice[i];
+      pSOverRc->iEndMbSlice     = pSliceInLayer[i].sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
     pSOverRc->iEndMbSlice      += (pCurSliceCtx->pCountMbNumInSlice[i] - 1);
     pSOverRc->iTotalQpSlice     = 0;
     pSOverRc->iTotalMbSlice     = 0;
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -81,9 +81,10 @@
                                    SMB* pMbList,
                                    const int32_t uiSliceIdc) {
   SSliceCtx* pSliceCtx           = &pCurDq->sSliceEncCtx;
+  SSlice* pUpdateSlice           = &pCurDq->sLayerInfo.pSliceInLayer[uiSliceIdc];
   const uint16_t* kpMbMap        = pSliceCtx->pOverallMbMap;
   const int32_t kiMbWidth        = pSliceCtx->iMbWidth;
-  int32_t iIdx                   = pSliceCtx->pFirstMbInSlice[uiSliceIdc];
+  int32_t iIdx                   = pUpdateSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
   const int32_t kiEndMbInSlice   = iIdx + pSliceCtx->pCountMbNumInSlice[uiSliceIdc] - 1;
 
   do {
@@ -816,10 +817,11 @@
           pEncPEncCtx->pSliceThreading->pSliceConsumeTime[pEncPEncCtx->uiDependencyId][iSliceIdx] = (uint32_t) (
                 WelsTime() - iSliceStart);
           MT_TRACE_LOG (& (pEncPEncCtx->sLogCtx), WELS_LOG_INFO,
-                        "[MT] CodingSliceThreadProc(), coding_idx %d, uiSliceIdx %d, pSliceConsumeTime %d, iSliceSize %d, pFirstMbInSlice %d, count_num_mb_in_slice %d",
+                        "[MT] CodingSliceThreadProc(), coding_idx %d, uiSliceIdx %d, pSliceConsumeTime %d, iSliceSize %d, iFirstMbInSlice %d, count_num_mb_in_slice %d",
                         pEncPEncCtx->iCodingIndex, iSliceIdx,
                         pEncPEncCtx->pSliceThreading->pSliceConsumeTime[pEncPEncCtx->uiDependencyId][iSliceIdx], iSliceSize,
-                        pCurDq->sSliceEncCtx.pFirstMbInSlice[iSliceIdx], pCurDq->sSliceEncCtx.pCountMbNumInSlice[iSliceIdx]);
+                        pCurDq->sLayerInfo.pSliceInLayer[iSliceIdx].sSliceHeaderExt.sSliceHeader.iFirstMbInSlice,
+                        pCurDq->sSliceEncCtx.pCountMbNumInSlice[iSliceIdx]);
         }
 
 #if defined(SLICE_INFO_OUTPUT)
@@ -847,10 +849,10 @@
         const int32_t kiFirstMbInPartition      = pPrivateData->iStartMbIndex;  // inclusive
         const int32_t kiEndMbInPartition        = pPrivateData->iEndMbIndex;            // exclusive
         int32_t iAnyMbLeftInPartition           = kiEndMbInPartition - kiFirstMbInPartition;
+        SSliceHeaderExt* pStartSliceHeaderExt   = &pCurDq->sLayerInfo.pSliceInLayer[iSliceIdx].sSliceHeaderExt;
 
         iSliceIdx = pPrivateData->iSliceIndex;
-
-        pSliceCtx->pFirstMbInSlice[iSliceIdx]                   = kiFirstMbInPartition;
+        pStartSliceHeaderExt->sSliceHeader.iFirstMbInSlice      = kiFirstMbInPartition;
         pCurDq->pNumSliceCodedOfPartition[kiPartitionId]        =
           1;    // one pSlice per partition intialized, dynamic slicing inside
         pCurDq->pLastMbIdxOfPartition[kiPartitionId]            = kiEndMbInPartition - 1;
@@ -1005,9 +1007,11 @@
   int32_t iEndMbIdx         = 0;
   int32_t iIdx              = 0;
   const int32_t kiEventCnt  = uiNumThreads;
-  int32_t       iLayerBsIdx = pCtx->pOut->iLayerBsIndex;
-  SLayerBSInfo* pLbi = &pFrameBsInfo->sLayerInfo[iLayerBsIdx];
+  int32_t iLayerBsIdx       = pCtx->pOut->iLayerBsIndex;
+  SLayerBSInfo* pLbi        = &pFrameBsInfo->sLayerInfo[iLayerBsIdx];
+  SSlice* pSliceInLayer     = pCtx->pCurDqLayer->sLayerInfo.pSliceInLayer;
 
+
   if (pPriData == NULL || pFrameBsInfo == NULL || pLbi == NULL || kiEventCnt <= 0 || pEventsList == NULL) {
     WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
              "FiredSliceThreads(), fail due pPriData == %p ||pFrameBsInfo == %p || pLbi == %p || iEventCnt(%d) <= 0 || pEventsList == %p!!",
@@ -1019,7 +1023,7 @@
   if (bIsDynamicSlicingMode) {
     iEndMbIdx = pSliceCtx->iMbNumInFrame;
     for (iIdx = kiEventCnt - 1; iIdx >= 0; --iIdx) {
-      const int32_t iFirstMbIdx         = pSliceCtx->pFirstMbInSlice[iIdx];
+      const int32_t iFirstMbIdx         = pSliceInLayer[iIdx].sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
       pPriData[iIdx].iStartMbIndex      = iFirstMbIdx;
       pPriData[iIdx].iEndMbIndex        = iEndMbIdx;
       iEndMbIdx                         = iFirstMbIdx;
--- a/codec/encoder/core/src/svc_enc_slice_segment.cpp
+++ b/codec/encoder/core/src/svc_enc_slice_segment.cpp
@@ -68,7 +68,9 @@
  * \return  0 - successful; none 0 - failed
  */
 int32_t AssignMbMapMultipleSlices (SDqLayer* pCurDq,const SSliceArgument* kpSliceArgument) {
-  SSliceCtx* pSliceSeg = &pCurDq->sSliceEncCtx;
+  SSliceCtx* pSliceSeg             = &pCurDq->sSliceEncCtx;
+  SSlice* pSliceInLayer            = pCurDq->sLayerInfo.pSliceInLayer;
+  SSliceHeaderExt* pSliceHeaderExt = NULL;
   int32_t iSliceIdx  = 0;
   if (NULL == pSliceSeg || SM_SINGLE_SLICE == pSliceSeg->uiSliceMode)
     return 1;
@@ -79,9 +81,10 @@
 
     iSliceIdx = 0;
     while (iSliceIdx < iSliceNum) {
-      const int32_t kiFirstMb = iSliceIdx * kiMbWidth;
-      pSliceSeg->pCountMbNumInSlice[iSliceIdx] = kiMbWidth;
-      pSliceSeg->pFirstMbInSlice[iSliceIdx]    = kiFirstMb;
+      const int32_t kiFirstMb                       = iSliceIdx * kiMbWidth;
+      SSliceHeaderExt* pSliceHeaderExt              = &pSliceInLayer[iSliceIdx].sSliceHeaderExt;
+      pSliceSeg->pCountMbNumInSlice[iSliceIdx]     = kiMbWidth;
+      pSliceHeaderExt->sSliceHeader.iFirstMbInSlice = kiFirstMb;
       WelsSetMemMultiplebytes_c(pSliceSeg->pOverallMbMap + kiFirstMb, iSliceIdx,
                                 kiMbWidth, sizeof(uint16_t));
       ++ iSliceIdx;
@@ -97,12 +100,12 @@
 
     iSliceIdx = 0;
     do {
-      const int32_t kiCurRunLength      = kpSlicesAssignList[iSliceIdx];
-      int32_t iRunIdx                   = 0;
+      const int32_t kiCurRunLength   = kpSlicesAssignList[iSliceIdx];
+      int32_t iRunIdx                = 0;
+      pSliceHeaderExt                = &pSliceInLayer[iSliceIdx].sSliceHeaderExt;
+      pSliceHeaderExt->sSliceHeader.iFirstMbInSlice = iMbIdx;
+      pSliceSeg->pCountMbNumInSlice[iSliceIdx]     = kiCurRunLength;
 
-      pSliceSeg->pFirstMbInSlice[iSliceIdx]     = iMbIdx;
-      pSliceSeg->pCountMbNumInSlice[iSliceIdx]  = kiCurRunLength;
-
       // due here need check validate mb_assign_map for input pData, can not use memset
       do {
         pSliceSeg->pOverallMbMap[iMbIdx + iRunIdx] = iSliceIdx;
@@ -113,13 +116,14 @@
       ++ iSliceIdx;
     } while (iSliceIdx < kiCountSliceNumInFrame && iMbIdx < kiCountNumMbInFrame);
   } else if (SM_SIZELIMITED_SLICE == pSliceSeg->uiSliceMode) {
-    const int32_t kiMaxSliceNum = pSliceSeg->iMaxSliceNumConstraint;
+    const int32_t kiMaxSliceNum       = pSliceSeg->iMaxSliceNumConstraint;
     const int32_t kiCountNumMbInFrame = pSliceSeg->iMbNumInFrame;
 
     iSliceIdx = 0;
     do {
-      pSliceSeg->pFirstMbInSlice[iSliceIdx] = 0;
-      pSliceSeg->pCountMbNumInSlice[iSliceIdx] = kiCountNumMbInFrame;
+      pSliceHeaderExt = &pSliceInLayer[iSliceIdx].sSliceHeaderExt;
+      pSliceHeaderExt->sSliceHeader.iFirstMbInSlice = 0;
+      pSliceSeg->pCountMbNumInSlice[iSliceIdx]     = kiCountNumMbInFrame;
       iSliceIdx++;
     } while (iSliceIdx < kiMaxSliceNum);
   } else { // any else uiSliceMode?
@@ -378,11 +382,7 @@
 
       pSliceSeg->pOverallMbMap = NULL;
     }
-    if (NULL != pSliceSeg->pFirstMbInSlice) {
-      pMa->WelsFree (pSliceSeg->pFirstMbInSlice, "pSliceSeg->pFirstMbInSlice");
 
-      pSliceSeg->pFirstMbInSlice = NULL;
-    }
     if (NULL != pSliceSeg->pCountMbNumInSlice) {
       pMa->WelsFree (pSliceSeg->pCountMbNumInSlice, "pSliceSeg->pCountMbNumInSlice");
 
@@ -407,11 +407,6 @@
     WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pOverallMbMap)
     pSliceSeg->iSliceNumInFrame = 1;
 
-    pSliceSeg->pFirstMbInSlice = (int32_t*)pMa->WelsMalloc (pSliceSeg->iSliceNumInFrame * sizeof (int32_t),
-                                  "pSliceSeg->pFirstMbInSlice");
-
-    WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pFirstMbInSlice)
-
     pSliceSeg->pCountMbNumInSlice = (int32_t*)pMa->WelsMalloc (pSliceSeg->iSliceNumInFrame * sizeof (int32_t),
                                     "pSliceSeg->pCountMbNumInSlice");
 
@@ -422,7 +417,6 @@
     pSliceSeg->iMbHeight                = kiMbHeight;
     pSliceSeg->iMbNumInFrame            = kiCountMbNum;
     pSliceSeg->pCountMbNumInSlice[0]    = kiCountMbNum;
-    pSliceSeg->pFirstMbInSlice[0]       = 0;
 
     return AssignMbMapSingleSlice (pSliceSeg->pOverallMbMap, kiCountMbNum, sizeof (pSliceSeg->pOverallMbMap[0]));
   } else { //if ( SM_MULTIPLE_SLICE == uiSliceMode )
@@ -444,10 +438,6 @@
                                     "pSliceSeg->pCountMbNumInSlice");
     WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pCountMbNumInSlice)
 
-    pSliceSeg->pFirstMbInSlice = (int32_t*)pMa->WelsMalloc (pSliceSeg->iSliceNumInFrame * sizeof (int32_t),
-                                    "pSliceSeg->pFirstMbInSlice");
-    WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pFirstMbInSlice)
-
     pSliceSeg->pSliceConsumeTime = (uint32_t*)pMa->WelsMalloc (pSliceSeg->iSliceNumInFrame * sizeof (uint32_t),
                                                              "pSliceSeg->pSliceConsumeTime");
     WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pSliceConsumeTime)
@@ -493,11 +483,7 @@
 
       pSliceSeg->pOverallMbMap = NULL;
     }
-    if (NULL != pSliceSeg->pFirstMbInSlice) {
-      pMa->WelsFree (pSliceSeg->pFirstMbInSlice, "pSliceSeg->pFirstMbInSlice");
 
-      pSliceSeg->pFirstMbInSlice = NULL;
-    }
     if (NULL != pSliceSeg->pCountMbNumInSlice) {
       pMa->WelsFree (pSliceSeg->pCountMbNumInSlice, "pSliceSeg->pCountMbNumInSlice");
 
@@ -583,13 +569,16 @@
 /*!
  * \brief   Get first mb in slice/slice_group: uiSliceIdc (apply in Single/multiple slices and FMO)
  *
- * \param   pSliceCtx       SSlice context
+ * \param   pSliceInLayer   slice list in current layer
  * \param   kuiSliceIdc     slice idc
  *
  * \return  iFirstMb - successful; -1 - failed;
  */
-int32_t WelsGetFirstMbOfSlice (SSliceCtx* pSliceCtx, const int32_t kuiSliceIdc) {
-  return pSliceCtx->pFirstMbInSlice[ kuiSliceIdc ];
+int32_t WelsGetFirstMbOfSlice (SSlice* pSliceInLayer, const int32_t kuiSliceIdc) {
+  if ( NULL == pSliceInLayer || NULL == &pSliceInLayer[kuiSliceIdc] )
+    return -1;
+
+  return pSliceInLayer[kuiSliceIdc].sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
 }
 
 /*!
@@ -689,6 +678,7 @@
 int32_t DynamicAdjustSlicePEncCtxAll (SDqLayer* pCurDq,
                                       int32_t* pRunLength) {
   SSliceCtx* pSliceCtx                  = &pCurDq->sSliceEncCtx;
+  SSlice* pSliceInLayer                 = pCurDq->sLayerInfo.pSliceInLayer;
   const int32_t iCountNumMbInFrame      = pSliceCtx->iMbNumInFrame;
   const int32_t iCountSliceNumInFrame   = pSliceCtx->iSliceNumInFrame;
   int32_t iSameRunLenFlag               = 1;
@@ -711,9 +701,9 @@
   iSliceIdx = 0;
   do {
     const int32_t kiSliceRun = pRunLength[iSliceIdx];
-
-    pSliceCtx->pFirstMbInSlice[iSliceIdx]    = iFirstMbIdx;
-    pSliceCtx->pCountMbNumInSlice[iSliceIdx] = kiSliceRun;
+    SSliceHeaderExt* pSliceHeaderExt              = &pSliceInLayer[iSliceIdx].sSliceHeaderExt;
+    pSliceHeaderExt->sSliceHeader.iFirstMbInSlice = iFirstMbIdx;
+    pSliceCtx->pCountMbNumInSlice[iSliceIdx]      = kiSliceRun;
 
     WelsSetMemMultiplebytes_c(pSliceCtx->pOverallMbMap + iFirstMbIdx, iSliceIdx,
                               kiSliceRun, sizeof(uint16_t));
--- 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->sSliceEncCtx, pSlice->uiSliceIdx);
+  pCurSliceHeader->iFirstMbInSlice = WelsGetFirstMbOfSlice (pCurLayer->sLayerInfo.pSliceInLayer, pSlice->uiSliceIdx);
 
   pCurSliceHeader->iFrameNum      = pEncCtx->iFrameNum;
   pCurSliceHeader->uiIdrPicId     = pEncCtx->uiIdrPicId;
@@ -818,6 +818,7 @@
 void AddSliceBoundary (sWelsEncCtx* pEncCtx, SSlice* pCurSlice, SSliceCtx* pSliceCtx, SMB* pCurMb,
                        int32_t iFirstMbIdxOfNextSlice, const int32_t kiLastMbIdxInPartition) {
   SDqLayer*     pCurLayer       = pEncCtx->pCurDqLayer;
+  SSlice*       pSliceInLayer   = pCurLayer->sLayerInfo.pSliceInLayer;
   int32_t       iCurMbIdx       = pCurMb->iMbXY;
   uint16_t      iCurSliceIdc    = pSliceCtx->pOverallMbMap[ iCurMbIdx ];
   const int32_t kiSliceIdxStep  = pEncCtx->iActiveThreadsNum;
@@ -842,8 +843,7 @@
     (NAL_UNIT_CODED_SLICE_EXT == pCurLayer->sLayerInfo.sNalHeaderExt.sNalUnitHeader.eNalUnitType);
   memcpy (&pNextSlice->sSliceHeaderExt, &pCurSlice->sSliceHeaderExt,
           sizeof (SSliceHeaderExt)); // confirmed_safe_unsafe_usage
-
-  pSliceCtx->pFirstMbInSlice[iNextSliceIdc] = iFirstMbIdxOfNextSlice;
+  pSliceInLayer[iNextSliceIdc].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
@@ -218,12 +218,12 @@
 
   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",
+           "[MT] CWelsLoadBalancingSlicingEncodingTask()FinishTask, coding_idx %d, um_iSliceIdx %d, pSliceConsumeTime %d, iSliceSize %d, iFirstMbInSlice %d, count_num_mb_in_slice %d",
            m_pCtx->iCodingIndex,
            m_iSliceIdx,
            m_pCtx->pCurDqLayer->sSliceEncCtx.pSliceConsumeTime[m_iSliceIdx],
            m_iSliceSize,
-           m_pCtx->pCurDqLayer->sSliceEncCtx.pFirstMbInSlice[m_iSliceIdx],
+           m_pCtx->pCurDqLayer->sLayerInfo.pSliceInLayer[m_iSliceIdx].sSliceHeaderExt.sSliceHeader.iFirstMbInSlice,
            m_pCtx->pCurDqLayer->sSliceEncCtx.pCountMbNumInSlice[m_iSliceIdx]);
 }