shithub: openh264

Download patch

ref: 612a0a3ff138aa79276eb2d7fd31b6c261123dd9
parent: 57016558ab1f5a73e26aac735900436b476000b7
author: huade <[email protected]>
date: Wed Dec 21 17:08:34 EST 2016

Multi-thread-fixed:RBC#1725:refactoring for ReOrderSliceInLayer module

--- a/codec/encoder/core/inc/svc_encode_slice.h
+++ b/codec/encoder/core/inc/svc_encode_slice.h
@@ -112,6 +112,8 @@
                        const int32_t kiDlayerIndex,
                        CMemoryAlign* pMa);
 
+int32_t InitAllSlicesInThread (sWelsEncCtx* pCtx);
+
 int32_t InitOneSliceInThread (sWelsEncCtx* pCtx,
                               SSlice*& pSlice,
                               const int32_t kiThreadIdx,
@@ -136,7 +138,15 @@
 
 int32_t ReallocSliceBuffer (sWelsEncCtx* pCtx);
 
-int32_t SliceLayerInfoUpdate (sWelsEncCtx* pCtx);
+int32_t FrameBsRealloc (sWelsEncCtx* pCtx,
+                        SFrameBSInfo* pFrameBsInfo,
+                        SLayerBSInfo* pLayerBsInfo,
+                        const int32_t kiMaxSliceNumOld);
+
+int32_t SliceLayerInfoUpdate (sWelsEncCtx* pCtx,
+                              SFrameBSInfo* pFrameBsInfo,
+                              SLayerBSInfo* pLayerBsInfo,
+                              const int32_t kiPartitionNum);
 
 //slice encoding process
 int32_t WelsCodePSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -4446,57 +4446,13 @@
   iRet = WelsEncoderParamAdjust (ppCtx, &sConfig);
   return iRet;
 }
-int32_t FrameBsRealloc (sWelsEncCtx* pCtx,
-                        SFrameBSInfo* pFrameBsInfo,
-                        SLayerBSInfo* pLayerBsInfo) {
-  CMemoryAlign* pMA = pCtx->pMemAlign;
-  SDqLayer* pCurLayer = pCtx->pCurDqLayer;
 
-  int32_t iCountNals = pCtx->pOut->iCountNals;
-  int32_t iMaxSliceNumOld = pCurLayer->iMaxSliceNum;
-  int32_t iMaxSliceNum = iMaxSliceNumOld;
-  iCountNals += iMaxSliceNum * (pCtx->pSvcParam->iSpatialLayerNum + pCtx->bNeedPrefixNalFlag);
-  iMaxSliceNum *= SLICE_NUM_EXPAND_COEF;
-
-  SWelsNalRaw* pNalList = (SWelsNalRaw*)pMA->WelsMallocz (iCountNals * sizeof (SWelsNalRaw), "pOut->sNalList");
-  if (NULL == pNalList) {
-    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::FrameBsRealloc: pNalList is NULL");
-    return ENC_RETURN_MEMALLOCERR;
-  }
-  memcpy (pNalList, pCtx->pOut->sNalList, sizeof (SWelsNalRaw) * pCtx->pOut->iCountNals);
-  pMA->WelsFree (pCtx->pOut->sNalList, "pOut->sNalList");
-  pCtx->pOut->sNalList = pNalList;
-
-  int32_t* pNalLen = (int32_t*)pMA->WelsMallocz (iCountNals * sizeof (int32_t), "pOut->pNalLen");
-  if (NULL == pNalLen) {
-    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::FrameBsRealloc: pNalLen is NULL");
-    return ENC_RETURN_MEMALLOCERR;
-  }
-  memcpy (pNalLen, pCtx->pOut->pNalLen, sizeof (int32_t) * pCtx->pOut->iCountNals);
-  pMA->WelsFree (pCtx->pOut->pNalLen, "pOut->pNalLen");
-  pCtx->pOut->pNalLen = pNalLen;
-
-  pCtx->pOut->iCountNals = iCountNals;
-  SLayerBSInfo* pLBI1, *pLBI2;
-  pLBI1 = &pFrameBsInfo->sLayerInfo[0];
-  pLBI1->pNalLengthInByte = pCtx->pOut->pNalLen;
-  while (pLBI1 != pLayerBsInfo) {
-    pLBI2 = pLBI1;
-    ++ pLBI1;
-    pLBI1->pNalLengthInByte = pLBI2->pNalLengthInByte + pLBI2->iNalCount;
-  }
-
-  return ENC_RETURN_SUCCESS;
-
-}
-
 int32_t DynSliceRealloc (sWelsEncCtx* pCtx,
                          SFrameBSInfo* pFrameBsInfo,
                          SLayerBSInfo* pLayerBsInfo) {
   int32_t iRet = 0;
 
-  iRet = FrameBsRealloc (pCtx, pFrameBsInfo, pLayerBsInfo);
-
+  iRet = FrameBsRealloc (pCtx, pFrameBsInfo, pLayerBsInfo, pCtx->pCurDqLayer->iMaxSliceNum);
   if(ENC_RETURN_SUCCESS != iRet) {
     return iRet;
   }
@@ -4571,7 +4527,6 @@
     }
 
     WelsLoadNal (pCtx->pOut, keNalType, keNalRefIdc);
-
     pCurSlice = &pCtx->pCurDqLayer->sSliceThreadInfo.pSliceInThread[uiTheadIdx][iSliceIdx];
     assert (iSliceIdx == pCurSlice->iSliceIdx);
 
@@ -4600,7 +4555,6 @@
 #endif//SLICE_INFO_OUTPUT
 
     ++ iNalIdxInLayer;
-
     iSliceIdx += kiSliceStep; //if iSliceIdx is not continuous
     iAnyMbLeftInPartition = iEndMbIdxInPartition - pCurLayer->pLastCodedMbIdxOfPartition[kiPartitionId];
   }
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -746,7 +746,6 @@
           }
 
           WelsLoadNalForSlice (pSliceBs, eNalType, eNalRefIdc);
-
           assert (iSliceIdx == pSlice->iSliceIdx);
           iReturn = WelsCodeOneSlice (pEncPEncCtx, pSlice, eNalType);
           if (ENC_RETURN_SUCCESS != iReturn) {
--- a/codec/encoder/core/src/svc_encode_slice.cpp
+++ b/codec/encoder/core/src/svc_encode_slice.cpp
@@ -977,6 +977,47 @@
   return ENC_RETURN_SUCCESS;
 }
 
+int32_t InitAllSlicesInThread (sWelsEncCtx* pCtx) {
+  SDqLayer* pDqLayer = pCtx->pCurDqLayer;
+  int32_t iSliceIdx  = 0;
+
+  for( ; iSliceIdx < pDqLayer->iMaxSliceNum; iSliceIdx++) {
+    if(NULL == pDqLayer->ppSliceInLayer[iSliceIdx]) {
+      return ENC_RETURN_UNEXPECTED;
+    }
+
+    pDqLayer->ppSliceInLayer[iSliceIdx]->iSliceIdx = -1;
+  }
+
+  return ENC_RETURN_SUCCESS;
+}
+
+int32_t InitOneSliceInThread (sWelsEncCtx* pCtx,
+                              SSlice*& pSlice,
+                              const int32_t kiThreadIdx,
+                              const int32_t kiDlayerIdx,
+                              const int32_t kiSliceIdx) {
+  SDqLayer* pDqLayer                  = pCtx->pCurDqLayer;
+  const int32_t kiCodedNumInThread    = pDqLayer->sSliceThreadInfo.iEncodedSliceNumInThread[kiThreadIdx];
+  const int32_t kiMaxSliceNumInThread = pDqLayer->sSliceThreadInfo.iMaxSliceNumInThread[kiThreadIdx];
+  int32_t iRet                        = 0;
+
+  if (kiCodedNumInThread >= kiMaxSliceNumInThread) {
+    iRet = ReallocateSliceInThread(pCtx, pDqLayer, kiDlayerIdx, kiThreadIdx);
+    if (ENC_RETURN_SUCCESS != iRet) {
+      return iRet;
+    }
+  }
+
+  pSlice = pDqLayer->sSliceThreadInfo.pSliceInThread [kiThreadIdx] + kiCodedNumInThread;
+  // Initialize slice bs buffer info
+  pSlice->sSliceBs.uiBsPos   = 0;
+  pSlice->sSliceBs.iNalIndex = 0;
+  pSlice->sSliceBs.pBsBuffer = pCtx->pSliceThreading->pThreadBsBuffer[kiThreadIdx];
+
+  return ENC_RETURN_SUCCESS;
+}
+
 int32_t InitSliceThreadInfo (sWelsEncCtx* pCtx,
                              SDqLayer* pDqLayer,
                              const int32_t kiDlayerIndex,
@@ -1214,25 +1255,21 @@
   return ENC_RETURN_SUCCESS;
 }
 
-int32_t ReallocSliceBuffer (sWelsEncCtx* pCtx) {
+int32_t ReallocateSliceInThread (sWelsEncCtx* pCtx,
+                                 SDqLayer* pDqLayer,
+                                 const int32_t kiDlayerIdx,
+                                 const int32_t kiThreadIndex) {
 
-  CMemoryAlign* pMA        = pCtx->pMemAlign;
-  SDqLayer* pCurLayer      = pCtx->pCurDqLayer;
-  SSlice** ppSlice         = NULL;
-  int32_t iMaxSliceNumOld  = pCurLayer->iMaxSliceNum;
-  int32_t iMaxSliceNumNew  = 0;
-  int32_t iRet             = 0;
-  int32_t iSliceIdx        = 0;
-  const int32_t kiCurDid   = pCtx->uiDependencyId;
+  int32_t iMaxSliceNumInThread   = pDqLayer->sSliceThreadInfo.iMaxSliceNumInThread[kiThreadIndex];
+  int32_t iMaxSliceNumUpdate     = 0;
+  int32_t iRet                   = 0;
+  SSlice* pLastCodedSlice        = pDqLayer->sSliceThreadInfo.pSliceInThread[kiThreadIndex] + (iMaxSliceNumInThread - 1);
+  SSliceArgument* pSliceArgument = & pCtx->pSvcParam->sSpatialLayers[kiDlayerIdx].sSliceArgument;
 
-  int32_t* pFirstMbIdxofSlice    = NULL;
-  int32_t* pCountMbNumInSlice    = NULL;
-  SSlice* pLastCodedSlice        = pCurLayer->sSliceThreadInfo.pSliceInThread[0] + (iMaxSliceNumOld - 1);
-  SSliceArgument* pSliceArgument = & pCtx->pSvcParam->sSpatialLayers[kiCurDid].sSliceArgument;
-  iRet = CalculateNewSliceNum (pCurLayer,
+  iRet = CalculateNewSliceNum (pDqLayer,
                                pLastCodedSlice,
-                               iMaxSliceNumOld,
-                               iMaxSliceNumNew);
+                               iMaxSliceNumInThread,
+                               iMaxSliceNumUpdate);
 
   if (ENC_RETURN_SUCCESS != iRet) {
     return iRet;
@@ -1240,17 +1277,29 @@
 
   iRet = ReallocateSliceList (pCtx,
                               pSliceArgument,
-                              pCurLayer->sSliceThreadInfo.pSliceInThread[0],
-                              iMaxSliceNumOld,
-                              iMaxSliceNumNew);
+                              pDqLayer->sSliceThreadInfo.pSliceInThread[kiThreadIndex],
+                              iMaxSliceNumInThread,
+                              iMaxSliceNumUpdate);
   if (ENC_RETURN_SUCCESS != iRet) {
     return iRet;
   }
 
+  return ENC_RETURN_SUCCESS;
+}
+
+int32_t ExtendLayerBuffer(sWelsEncCtx* pCtx,
+                          const int32_t kiMaxSliceNumOld,
+                          const int32_t kiMaxSliceNumNew){
+  CMemoryAlign* pMA            = pCtx->pMemAlign;
+  SDqLayer* pCurLayer          = pCtx->pCurDqLayer;
+  SSlice** ppSlice             = NULL;
+  int32_t* pFirstMbIdxofSlice  = NULL;
+  int32_t* pCountMbNumInSlice  = NULL;
+
   // update for ppsliceInlayer
-  ppSlice = (SSlice**)pMA->WelsMallocz (sizeof (SSlice*) * iMaxSliceNumNew, "ppSlice");
+  ppSlice = (SSlice**)pMA->WelsMallocz (sizeof (SSlice*) * kiMaxSliceNumNew, "ppSlice");
   if (NULL == ppSlice) {
-    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::ReallocSliceBuffer: ppSlice is NULL");
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::ExtendLayerBuffer: ppSlice is NULL");
     return ENC_RETURN_MEMALLOCERR;
   }
   pMA->WelsFree (pCurLayer->ppSliceInLayer, "ppSliceInLayer");
@@ -1257,28 +1306,63 @@
   pCurLayer->ppSliceInLayer = ppSlice;
 
   // update for pFirstMbIdxInSlice
-  pFirstMbIdxofSlice = (int32_t*)pMA->WelsMallocz (sizeof (int32_t*) * iMaxSliceNumNew, "pFirstMbIdxofSlice");
+  pFirstMbIdxofSlice = (int32_t*)pMA->WelsMallocz (sizeof (int32_t*) * kiMaxSliceNumNew, "pFirstMbIdxofSlice");
   if (NULL == pFirstMbIdxofSlice) {
-    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::ReallocSliceBuffer: pFirstMbIdxofSlice is NULL");
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::ExtendLayerBuffer: pFirstMbIdxofSlice is NULL");
     return ENC_RETURN_MEMALLOCERR;
   }
-  memset (pFirstMbIdxofSlice, 0, sizeof(int32_t) * iMaxSliceNumNew);
-  memcpy (pFirstMbIdxofSlice, pCurLayer->pFirstMbIdxOfSlice, sizeof (int32_t) * iMaxSliceNumOld);
+  memset (pFirstMbIdxofSlice, 0, sizeof(int32_t) * kiMaxSliceNumNew);
+  memcpy (pFirstMbIdxofSlice, pCurLayer->pFirstMbIdxOfSlice, sizeof (int32_t) * kiMaxSliceNumOld);
   pMA->WelsFree (pCurLayer->pFirstMbIdxOfSlice, "pFirstMbIdxofSlice");
   pCurLayer->pFirstMbIdxOfSlice = pFirstMbIdxofSlice;
 
   // update for pCountMbNumInSlice
-  pCountMbNumInSlice = (int32_t*)pMA->WelsMallocz (sizeof (int32_t*) * iMaxSliceNumNew, "pCountMbNumInSlice");
+  pCountMbNumInSlice = (int32_t*)pMA->WelsMallocz (sizeof (int32_t*) * kiMaxSliceNumNew, "pCountMbNumInSlice");
   if (NULL == pCountMbNumInSlice) {
-    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::ReallocSliceBuffer: pCountMbNumInSlice is NULL");
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::ExtendLayerBuffer: pCountMbNumInSlice is NULL");
     return ENC_RETURN_MEMALLOCERR;
   }
-  memset (pCountMbNumInSlice, 0, sizeof(int32_t) * iMaxSliceNumNew);
-  memcpy (pCountMbNumInSlice, pCurLayer->pCountMbNumInSlice, sizeof (int32_t) * iMaxSliceNumOld);
+  memset (pCountMbNumInSlice, 0, sizeof(int32_t) * kiMaxSliceNumNew);
+  memcpy (pCountMbNumInSlice, pCurLayer->pCountMbNumInSlice, sizeof (int32_t) * kiMaxSliceNumOld);
   pMA->WelsFree (pCurLayer->pCountMbNumInSlice, "pCountMbNumInSlice");
   pCurLayer->pCountMbNumInSlice = pCountMbNumInSlice;
 
+  return ENC_RETURN_SUCCESS;
+}
 
+int32_t ReallocSliceBuffer (sWelsEncCtx* pCtx) {
+
+  SDqLayer* pCurLayer      = pCtx->pCurDqLayer;
+  int32_t iMaxSliceNumOld  = pCurLayer->iMaxSliceNum;
+  int32_t iMaxSliceNumNew  = 0;
+  int32_t iRet             = 0;
+  int32_t iSliceIdx        = 0;
+  const int32_t kiCurDid   = pCtx->uiDependencyId;
+  SSlice* pLastCodedSlice        = pCurLayer->sSliceThreadInfo.pSliceInThread[0] + (iMaxSliceNumOld - 1);
+  SSliceArgument* pSliceArgument = & pCtx->pSvcParam->sSpatialLayers[kiCurDid].sSliceArgument;
+  iRet = CalculateNewSliceNum (pCurLayer,
+                               pLastCodedSlice,
+                               iMaxSliceNumOld,
+                               iMaxSliceNumNew);
+
+  if (ENC_RETURN_SUCCESS != iRet) {
+    return iRet;
+  }
+
+  iRet = ReallocateSliceList (pCtx,
+                              pSliceArgument,
+                              pCurLayer->sSliceThreadInfo.pSliceInThread[0],
+                              iMaxSliceNumOld,
+                              iMaxSliceNumNew);
+  if (ENC_RETURN_SUCCESS != iRet) {
+    return iRet;
+  }
+
+  iRet = ExtendLayerBuffer(pCtx, iMaxSliceNumOld, iMaxSliceNumNew);
+  if (ENC_RETURN_SUCCESS != iRet) {
+    return iRet;
+  }
+
   for (iSliceIdx = 0; iSliceIdx < iMaxSliceNumNew; iSliceIdx++) {
     pCurLayer->ppSliceInLayer[iSliceIdx] = pCurLayer->sSliceThreadInfo.pSliceInThread[0] + iSliceIdx;
   }
@@ -1292,6 +1376,22 @@
   return ENC_RETURN_SUCCESS;
 }
 
+static inline int32_t CheckAllSliceBuffer(SDqLayer* pCurLayer, const int32_t kiCodedSliceNum) {
+  int32_t iSliceIdx = 0;
+  for(; iSliceIdx <kiCodedSliceNum ; iSliceIdx ++ ) {
+    if ( NULL == pCurLayer->ppSliceInLayer[iSliceIdx]) {
+      return ENC_RETURN_UNEXPECTED;
+    }
+
+    if ( iSliceIdx != pCurLayer->ppSliceInLayer[iSliceIdx]->iSliceIdx) {
+      return ENC_RETURN_UNEXPECTED;
+    }
+  }
+
+  return ENC_RETURN_SUCCESS;
+}
+
+
 int32_t ReOrderSliceInLayer (SDqLayer* pCurLayer,
                              const int32_t kiThreadNum,
                              const int32_t kiPartitionNum) {
@@ -1301,18 +1401,26 @@
   int32_t iPartitionID      = 0;
   int32_t iSliceIdx         = 0;
   int32_t iSliceNumInThread = 0;
-  int32_t iPartitionOffset  = 0;
+  int32_t iEncodeSliceNum   = 0;
   int32_t iActualSliceIdx   = 0;
+  int32_t iNonUsedBufferNum = 0;
+  int32_t iUsedSliceNum     = 0;
   int32_t aiPartitionOffset[MAX_THREADS_NUM] = {0};
 
   //for non-dynamic slice mode, kiPartitionNum = 1, iPartitionOffset = 0
   for(iPartitionIdx = 0; iPartitionIdx < kiPartitionNum; iPartitionIdx++) {
-    aiPartitionOffset[iPartitionIdx] = iPartitionOffset;
-    iPartitionOffset                += pCurLayer->pNumSliceCodedOfPartition[iPartitionIdx];
+    aiPartitionOffset[iPartitionIdx] = iEncodeSliceNum;
+    iEncodeSliceNum                 += pCurLayer->pNumSliceCodedOfPartition[iPartitionIdx];
   }
 
+  if( iEncodeSliceNum != pCurLayer->sSliceEncCtx.iSliceNumInFrame) {
+    return ENC_RETURN_UNEXPECTED;
+  }
+
+  //before encode all slices in layer, slices' index are init with -1
+  //pSliceInThread->iSliceIdx will be set to actual slice index when encode one slice
   for (iThreadIdx = 0; iThreadIdx < kiThreadNum; iThreadIdx++) {
-    iSliceNumInThread = pCurLayer->sSliceThreadInfo.iEncodedSliceNumInThread[iThreadIdx];
+    iSliceNumInThread = pCurLayer->sSliceThreadInfo.iMaxSliceNumInThread[iThreadIdx];
 
     for(iSliceIdx =0; iSliceIdx < iSliceNumInThread; iSliceIdx++) {
       pSliceInThread = pCurLayer->sSliceThreadInfo.pSliceInThread[iThreadIdx] + iSliceIdx;
@@ -1320,65 +1428,99 @@
         return ENC_RETURN_UNEXPECTED;
       }
 
-      iPartitionID    = pSliceInThread->iSliceIdx % kiPartitionNum;
-      iActualSliceIdx = aiPartitionOffset[iPartitionID] + pSliceInThread->iSliceIdx / kiPartitionNum;
-      pCurLayer->ppSliceInLayer[iActualSliceIdx] = pSliceInThread;
+      if( -1 != pSliceInThread->iSliceIdx) {
+        iPartitionID    = pSliceInThread->iSliceIdx % kiPartitionNum;
+        iActualSliceIdx = aiPartitionOffset[iPartitionID] + pSliceInThread->iSliceIdx / kiPartitionNum;
+        pCurLayer->ppSliceInLayer[iActualSliceIdx] = pSliceInThread;
+        iUsedSliceNum ++;
+      } else {
+          pCurLayer->ppSliceInLayer[iEncodeSliceNum + iNonUsedBufferNum] = pSliceInThread;
+          iNonUsedBufferNum ++;
+      }
     }
   }
 
+  if( iUsedSliceNum != iEncodeSliceNum ||
+     pCurLayer->iMaxSliceNum != (iNonUsedBufferNum + iUsedSliceNum)) {
+    return ENC_RETURN_UNEXPECTED;
+  }
+
+  if (ENC_RETURN_SUCCESS != CheckAllSliceBuffer(pCurLayer, iEncodeSliceNum)) {
+    return ENC_RETURN_UNEXPECTED;
+  }
+
   return ENC_RETURN_SUCCESS;
 }
 
-static inline int32_t CheckAllSliceBuffer(SDqLayer* pCurLayer, const int32_t kiCodedSliceNum) {
-  int32_t iSliceIdx = 0;
-  for(; iSliceIdx <kiCodedSliceNum ; iSliceIdx ++ ) {
-    if ( NULL == pCurLayer->ppSliceInLayer[iSliceIdx]) {
-      return ENC_RETURN_UNEXPECTED;
-    }
+int32_t FrameBsRealloc (sWelsEncCtx* pCtx,
+                        SFrameBSInfo* pFrameBsInfo,
+                        SLayerBSInfo* pLayerBsInfo,
+                        const int32_t kiMaxSliceNumOld) {
+  CMemoryAlign* pMA  = pCtx->pMemAlign;
+  int32_t iCountNals = pCtx->pOut->iCountNals;
+  iCountNals += kiMaxSliceNumOld * (pCtx->pSvcParam->iSpatialLayerNum + pCtx->bNeedPrefixNalFlag);
 
-    if ( iSliceIdx != pCurLayer->ppSliceInLayer[iSliceIdx]->iSliceIdx) {
-      return ENC_RETURN_UNEXPECTED;
-    }
+  SWelsNalRaw* pNalList = (SWelsNalRaw*)pMA->WelsMallocz (iCountNals * sizeof (SWelsNalRaw), "pOut->sNalList");
+  if (NULL == pNalList) {
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::FrameBsRealloc: pNalList is NULL");
+    return ENC_RETURN_MEMALLOCERR;
   }
+  memcpy (pNalList, pCtx->pOut->sNalList, sizeof (SWelsNalRaw) * pCtx->pOut->iCountNals);
+  pMA->WelsFree (pCtx->pOut->sNalList, "pOut->sNalList");
+  pCtx->pOut->sNalList = pNalList;
 
+  int32_t* pNalLen = (int32_t*)pMA->WelsMallocz (iCountNals * sizeof (int32_t), "pOut->pNalLen");
+  if (NULL == pNalLen) {
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::FrameBsRealloc: pNalLen is NULL");
+    return ENC_RETURN_MEMALLOCERR;
+  }
+  memcpy (pNalLen, pCtx->pOut->pNalLen, sizeof (int32_t) * pCtx->pOut->iCountNals);
+  pMA->WelsFree (pCtx->pOut->pNalLen, "pOut->pNalLen");
+  pCtx->pOut->pNalLen = pNalLen;
+
+  pCtx->pOut->iCountNals = iCountNals;
+  SLayerBSInfo* pLBI1, *pLBI2;
+  pLBI1 = &pFrameBsInfo->sLayerInfo[0];
+  pLBI1->pNalLengthInByte = pCtx->pOut->pNalLen;
+  while (pLBI1 != pLayerBsInfo) {
+    pLBI2 = pLBI1;
+    ++ pLBI1;
+    pLBI1->pNalLengthInByte = pLBI2->pNalLengthInByte + pLBI2->iNalCount;
+  }
+
   return ENC_RETURN_SUCCESS;
 }
 
-int32_t SliceLayerInfoUpdate (sWelsEncCtx* pCtx, const int32_t kiDlayerIndex) {
-
-  CMemoryAlign* pMA       = pCtx->pMemAlign;
+int32_t SliceLayerInfoUpdate (sWelsEncCtx* pCtx,
+                              SFrameBSInfo* pFrameBsInfo,
+                              SLayerBSInfo* pLayerBsInfo,
+                              const int32_t kiPartitionNum) {
   SDqLayer* pCurLayer     = pCtx->pCurDqLayer;
-  SSlice** ppSlice        = NULL;
-  int32_t iCodedSliceNum  = 0;
+  int32_t iMaxSliceNum    = 0;
   int32_t iThreadIdx      = 0;
   int32_t iRet            = 0;
   int32_t iThreadNum      = 1; //TODO: should be equal to pCurLayer->iMaxSliceNum;
-  SSliceArgument* pSliceArgument = & pCtx->pSvcParam->sSpatialLayers[kiDlayerIndex].sSliceArgument;
-  int32_t iPartitionNum   = (SM_SIZELIMITED_SLICE == pSliceArgument->uiSliceMode) ? pCtx->iActiveThreadsNum : 1;
 
   for ( ; iThreadIdx < iThreadNum; iThreadIdx++) {
-    iCodedSliceNum += pCurLayer->sSliceThreadInfo.iMaxSliceNumInThread[iThreadIdx];
+    iMaxSliceNum += pCurLayer->sSliceThreadInfo.iMaxSliceNumInThread[iThreadIdx];
   }
 
-  if (iCodedSliceNum <= 0) {
-    return ENC_RETURN_UNEXPECTED;
-  }
-
   //reallocate ppSliceInLayer if total encoded slice num exceed max slice num
-  if (iCodedSliceNum > pCurLayer->iMaxSliceNum) {
-    ppSlice = (SSlice**)pMA->WelsMallocz (sizeof (SSlice*) * iCodedSliceNum, "ppSlice");
-    if (NULL == ppSlice) {
-      WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR, "CWelsH264SVCEncoder::SliceLayerInfoUpdate: ppSlice is NULL");
-      return ENC_RETURN_MEMALLOCERR;
+  if (iMaxSliceNum > pCurLayer->iMaxSliceNum) {
+    iRet = FrameBsRealloc (pCtx, pFrameBsInfo, pLayerBsInfo, pCtx->pCurDqLayer->iMaxSliceNum);
+    if(ENC_RETURN_SUCCESS != iRet) {
+      return iRet;
     }
 
-    pMA->WelsFree (pCurLayer->ppSliceInLayer, "ppSliceInLayer");
-    pCurLayer->ppSliceInLayer = ppSlice;
-    pCurLayer->iMaxSliceNum = iCodedSliceNum;
+    iRet = ExtendLayerBuffer(pCtx, pCtx->pCurDqLayer->iMaxSliceNum, iMaxSliceNum);
+    if (ENC_RETURN_SUCCESS != iRet) {
+      return iRet;
+    }
+    pCurLayer->iMaxSliceNum = iMaxSliceNum;
   }
 
   //update ppSliceInLayer based on pSliceInThread, reordering based on slice index
-  iRet = ReOrderSliceInLayer (pCurLayer, iThreadNum, iPartitionNum);
+  iRet = ReOrderSliceInLayer (pCurLayer, iThreadNum, kiPartitionNum);
   if (ENC_RETURN_SUCCESS != iRet) {
     WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
              "CWelsH264SVCEncoder::SliceLayerInfoUpdate: ReOrderSliceInLayer failed");
@@ -1385,13 +1527,6 @@
     return iRet;
   }
 
-  iRet = CheckAllSliceBuffer(pCurLayer, pCtx->iActiveThreadsNum);
-  if (ENC_RETURN_SUCCESS != iRet) {
-    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
-             "CWelsH264SVCEncoder::SliceLayerInfoUpdate: ReOrderSliceInLayerDynamic failed");
-    return iRet;
-  }
-
   return ENC_RETURN_SUCCESS;
 }
 
@@ -1449,7 +1584,6 @@
   } while ((iIdx < kiEndMbNeedUpdate) &&
            (iIdx <= kiLastMbIdxInPartition));
 }
-
 
 void AddSliceBoundary (sWelsEncCtx* pEncCtx, SSlice* pCurSlice, SSliceCtx* pSliceCtx, SMB* pCurMb,
                        int32_t iFirstMbIdxOfNextSlice, const int32_t kiLastMbIdxInPartition) {
--- a/codec/encoder/core/src/wels_task_encoder.cpp
+++ b/codec/encoder/core/src/wels_task_encoder.cpp
@@ -166,7 +166,6 @@
   }
 
   WelsLoadNalForSlice (m_pSliceBs, m_eNalType, m_eNalRefIdc);
-
   assert (m_iSliceIdx == (int) m_pSlice->iSliceIdx);
   int32_t iReturn = WelsCodeOneSlice (m_pCtx, m_pSlice, m_eNalType);
   if (ENC_RETURN_SUCCESS != iReturn) {
--- /dev/null
+++ b/run_NasmCheck.sh
@@ -1,0 +1,15 @@
+#!/bin/bash
+
+echo "test common!"
+nasm=""
+nasm_list=(nasm /usr/bin/nasm /opt/local/bin/nasm)
+for cmd in ${nasm_list[@]}
+do
+    ver=`$cmd -v 2>/dev/null | awk '{print $3}'`
+	[[ $ver =~ ^2\.1[0-9] ]] && nasm=$cmd && break
+done
+
+echo "ver is $ver"
+echo "nasm is $nasm"
+[ "$nasm" = "" ] && echo "[Error] pls install nasm (2.10+)" 1>&2 && exit 1
+