ref: 7f172770a255fdabb142ace0ebab099bb3a19efa
parent: a4caef0fa3b700927b005d6d31706476ada84a55
parent: 71750df1cc651fc435e7e19aed6f9cf111e9d76e
author: sijchen <sijchen@cisco.com>
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;
}