shithub: openh264

Download patch

ref: 37a6e8fac05abd8c7aa2f8c6cd9e26eceb1d8ee9
parent: 4ca5d946b73de0cc1eec598fcf482b1786ddf13f
author: huade <huashi@cisco.com>
date: Tue Dec 20 02:15:08 EST 2016

Multi-thread-fixed:RBC#1683:add ppSlice update module

--- a/codec/encoder/core/inc/svc_encode_slice.h
+++ b/codec/encoder/core/inc/svc_encode_slice.h
@@ -133,6 +133,8 @@
 
 int32_t ReallocSliceBuffer (sWelsEncCtx* pCtx);
 
+int32_t SliceLayerInfoUpdate (sWelsEncCtx* pCtx);
+
 //slice encoding process
 int32_t WelsCodePSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);
 int32_t WelsCodePOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -989,7 +989,6 @@
   pRefList = NULL;
 }
 
-
 /*!
  * \brief   initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available
  * \pParam  pCtx            sWelsEncCtx*
@@ -3781,6 +3780,9 @@
                    pParam->sSliceArgument.uiSliceMode, pCtx->iEncoderError);
           return pCtx->iEncoderError;
         }
+
+        //TO DO: add update ppSliceInLayer module based on pSliceInThread[ThreadNum]
+        // UpdateSliceInLayerInfo(); // reordering
 
         //TO DO: add update ppSliceInLayer module based on pSliceInThread[ThreadNum]
         // UpdateSliceInLayerInfo(); // reordering
--- a/codec/encoder/core/src/ref_list_mgr_svc.cpp
+++ b/codec/encoder/core/src/ref_list_mgr_svc.cpp
@@ -700,7 +700,6 @@
 void WelsUpdateRefSyntax (sWelsEncCtx* pCtx, const int32_t iPOC, const int32_t uiFrameType) {
 
   int32_t iAbsDiffPicNumMinus1   = -1;
-
   SSlice** ppSliceList = NULL;
   SSpatialLayerInternal* pParamD    = &pCtx->pSvcParam->sDependencyLayers[pCtx->uiDependencyId];
   /*syntax for ref_pic_list_reordering()*/
@@ -984,6 +983,8 @@
   }
 
   const int32_t iSliceNum = GetCurrentSliceNum (pCtx->pCurDqLayer);
+
+
   ppSliceList = pCtx->pCurDqLayer->ppSliceInLayer;
   WlesMarkMMCORefInfoScreen (pCtx, pLtr, ppSliceList, iSliceNum);
 
--- a/codec/encoder/core/src/svc_enc_slice_segment.cpp
+++ b/codec/encoder/core/src/svc_enc_slice_segment.cpp
@@ -536,6 +536,8 @@
   if ( NULL == ppSliceInLayer || NULL == ppSliceInLayer[kuiSliceIdc] ) {
     return -1;
   }
+
+
   return ppSliceInLayer[kuiSliceIdc]->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice;
 }
 
--- a/codec/encoder/core/src/svc_encode_slice.cpp
+++ b/codec/encoder/core/src/svc_encode_slice.cpp
@@ -1325,6 +1325,110 @@
   return ENC_RETURN_SUCCESS;
 }
 
+/*
+int32_t ReOrderSliceInLayer (SDqLayer* pCurLayer,
+                             const int32_t kiThreadNum,
+                             const int32_t kiPartitionNum) {
+  SSlice* pSliceInThread    = NULL;
+  int32_t iThreadIdx        = 0;
+  int32_t iPartitionIdx     = 0;
+  int32_t iPartitionID      = 0;
+  int32_t iSliceIdx         = 0;
+  int32_t iSliceNumInThread = 0;
+  int32_t iPartitionOffset  = 0;
+  int32_t iActualSliceIdx   = 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];
+  }
+
+  for (iThreadIdx = 0; iThreadIdx < kiThreadNum; iThreadIdx++) {
+    iSliceNumInThread = pCurLayer->sSliceThreadInfo.iEncodedSliceNumInThread[iThreadIdx];
+
+    for(iSliceIdx =0; iSliceIdx < iSliceNumInThread; iSliceIdx++) {
+      pSliceInThread = pCurLayer->sSliceThreadInfo.pSliceInThread[iThreadIdx] + iSliceIdx;
+      if (NULL == pSliceInThread) {
+        return ENC_RETURN_UNEXPECTED;
+      }
+
+      iPartitionID    = pSliceInThread->uiSliceIdx % kiPartitionNum;
+      iActualSliceIdx = aiPartitionOffset[iPartitionID] + pSliceInThread->uiSliceIdx / kiPartitionNum;
+      pCurLayer->ppSliceInLayer[iActualSliceIdx] = pSliceInThread;
+    }
+  }
+
+  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]->uiSliceIdx) {
+      return ENC_RETURN_UNEXPECTED;
+    }
+  }
+
+  return ENC_RETURN_SUCCESS;
+}
+
+int32_t SliceLayerInfoUpdate (sWelsEncCtx* pCtx, const int32_t kiDlayerIndex) {
+
+  CMemoryAlign* pMA       = pCtx->pMemAlign;
+  SDqLayer* pCurLayer     = pCtx->pCurDqLayer;
+  SSlice** ppSlice        = NULL;
+  int32_t iCodedSliceNum  = 0;
+  int32_t iThreadIdx      = 0;
+  int32_t iRet            = 0;
+  SSliceArgument* pSliceArgument = & pCtx->pSvcParam->sSpatialLayers[kiDlayerIndex].sSliceArgument;
+  int32_t iPartitionNum   = (SM_SIZELIMITED_SLICE == pSliceArgument->uiSliceMode) ? pCtx->iActiveThreadsNum : 1;
+
+  for ( ; iThreadIdx < pCtx->iActiveThreadsNum; iThreadIdx++) {
+    iCodedSliceNum += 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->sSliceEncCtx.iMaxSliceNumConstraint) {
+    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;
+    }
+
+    pMA->WelsFree (pCurLayer->ppSliceInLayer, "ppSliceInLayer");
+    pCurLayer->ppSliceInLayer = ppSlice;
+    pCurLayer->sSliceEncCtx.iMaxSliceNumConstraint = iCodedSliceNum;
+  }
+
+  //update ppSliceInLayer based on pSliceInThread, reordering based on slice index
+  iRet = ReOrderSliceInLayer (pCurLayer, pCtx->iActiveThreadsNum, iPartitionNum);
+  if (ENC_RETURN_SUCCESS != iRet) {
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
+             "CWelsH264SVCEncoder::SliceLayerInfoUpdate: ReOrderSliceInLayer failed");
+    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;
+}
+*/
+
 int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const int32_t kiNalType) {
   SDqLayer* pCurLayer                   = pEncCtx->pCurDqLayer;
   SNalUnitHeaderExt* pNalHeadExt        = &pCurLayer->sLayerInfo.sNalHeaderExt;
--- a/codec/encoder/core/src/wels_task_encoder.cpp
+++ b/codec/encoder/core/src/wels_task_encoder.cpp
@@ -234,7 +234,8 @@
 
   SSliceCtx* pSliceCtx                    = &pCurDq->sSliceEncCtx;
   const int32_t kiSliceIdxStep            = m_pCtx->iActiveThreadsNum;
-  SSpatialLayerInternal* pParamInternal   = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];
+
+  SSpatialLayerInternal* pParamInternal = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId];
   SSliceHeaderExt* pStartSliceHeaderExt   = &pCurDq->ppSliceInLayer[m_iSliceIdx]->sSliceHeaderExt;
 
   //deal with partition: TODO: here SSliceThreadPrivateData is just for parition info and actually has little relationship with threadbuffer, and iThreadIndex is not used in threadpool model, need renaming after removing old logic to avoid confusion