Merge pull request #2421 from shihuade/MultiThread_V5.2_Pull_V2

refactor for slice buffer init/allocate/free
This commit is contained in:
sijchen 2016-03-22 16:20:37 -07:00
commit 40e1a69fae
7 changed files with 334 additions and 158 deletions

View File

@ -90,11 +90,6 @@ uint8_t* pThreadBsBuffer[MAX_THREADS_NUM]; //actual memor
bool bThreadBsBufferUsage[MAX_THREADS_NUM];
WELS_MUTEX mutexThreadBsBufferUsage;
SSlice* pSliceInThread[MAX_THREADS_NUM]; //slice buffer
int32_t* piSliceIndexInThread[MAX_THREADS_NUM];
int32_t iMaxSliceNumInThread[MAX_THREADS_NUM];
int32_t iEncodedSliceNumInThread[MAX_THREADS_NUM];
} SSliceThreading;
#endif//MULTIPLE_THREADING_DEFINES_H__

View File

@ -68,10 +68,17 @@ uint8_t uiFMEGoodFrameCount;
int32_t iHighFreMbCount;
} SFeatureSearchPreparation; //maintain only one
typedef struct TagSliceThreadInfo {
SSlice* pSliceInThread[MAX_THREADS_NUM];// slice buffer for multi thread,
// will not alloated when multi thread is off
int32_t iMaxSliceNumInThread[MAX_THREADS_NUM];
int32_t iEncodedSliceNumInThread[MAX_THREADS_NUM];
}SSliceThreadInfo;
typedef struct TagLayerInfo {
SNalUnitHeaderExt sNalHeaderExt;
SSlice*
pSliceInLayer;// Here SSlice identify to Frame on concept, [iSliceIndex], need memory block external side for MT
SSlice* pSliceInLayer; // Here SSlice identify to Frame on concept, [iSliceIndex],
// may need extend list size for sliceMode=SM_SIZELIMITED_SLICE
SSubsetSps* pSubsetSpsP; // current pSubsetSps used, memory alloc in external
SWelsSPS* pSpsP; // current pSps based avc used, memory alloc in external
SWelsPPS* pPpsP; // current pPps used
@ -79,6 +86,8 @@ SWelsPPS* pPpsP; // current pPps used
/* Layer Representation */
struct TagDqLayer {
SLayerInfo sLayerInfo;
SSliceThreadInfo sSliceThreadInfo;
SSlice** ppSliceInLayer;
SSliceCtx sSliceEncCtx; // current slice context
uint8_t* pCsData[3]; // pointer to reconstructed picture pData
int32_t iCsStride[3]; // Cs stride

View File

@ -80,6 +80,30 @@ int32_t WelsPSliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice, const boo
int32_t WelsISliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice); // for intra non-dynamic slice
int32_t WelsISliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice); // for intra dynamic slice
//slice buffer init, allocate and free process
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,
CMemoryAlign* pMa);
int32_t AllocateSliceMBBuffer (SSlice* pSlice, CMemoryAlign* pMa);
int32_t InitSliceBsBuffer (SSlice* pSlice,
SBitStringAux* pBsWrite,
bool bIndependenceBsBuffer,
const int32_t iMaxSliceBufferSize,
CMemoryAlign* pMa);
void FreeSliceBuffer(SSlice*& pSliceList,
const int32_t kiMaxSliceNum,
CMemoryAlign* pMa,
const char* kpTag);
//slice encoding process
int32_t WelsCodePSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);
int32_t WelsCodePOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);

View File

@ -894,61 +894,14 @@ int32_t InitMbListD (sWelsEncCtx** ppCtx) {
return 0;
}
void FreeSliceInLayer (SDqLayer* pDq, CMemoryAlign* pMa) {
int32_t iIdx = 0;
int32_t AllocMbCacheAligned (SMbCache* pMbCache, CMemoryAlign* pMa) {
pMbCache->pCoeffLevel = (int16_t*)pMa->WelsMallocz (MB_COEFF_LIST_SIZE * sizeof (int16_t), "pMbCache->pCoeffLevel");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pCoeffLevel));
pMbCache->pMemPredMb = (uint8_t*)pMa->WelsMallocz (2 * 256 * sizeof (uint8_t), "pMbCache->pMemPredMb");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pMemPredMb));
pMbCache->pSkipMb = (uint8_t*)pMa->WelsMallocz (384 * sizeof (uint8_t), "pMbCache->pSkipMb");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pSkipMb));
pMbCache->pMemPredBlk4 = (uint8_t*)pMa->WelsMallocz (2 * 16 * sizeof (uint8_t), "pMbCache->pMemPredBlk4");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pMemPredBlk4));
pMbCache->pBufferInterPredMe = (uint8_t*)pMa->WelsMallocz (4 * 640 * sizeof (uint8_t), "pMbCache->pBufferInterPredMe");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pBufferInterPredMe));
pMbCache->pPrevIntra4x4PredModeFlag = (bool*)pMa->WelsMallocz (16 * sizeof (bool),
"pMbCache->pPrevIntra4x4PredModeFlag");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pPrevIntra4x4PredModeFlag));
pMbCache->pRemIntra4x4PredModeFlag = (int8_t*)pMa->WelsMallocz (16 * sizeof (int8_t),
"pMbCache->pRemIntra4x4PredModeFlag");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pRemIntra4x4PredModeFlag));
pMbCache->pDct = (SDCTCoeff*)pMa->WelsMallocz (sizeof (SDCTCoeff), "pMbCache->pDct");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pDct));
return 0;
}
void FreeMbCache (SMbCache* pMbCache, CMemoryAlign* pMa) {
if (NULL != pMbCache->pCoeffLevel) {
pMa->WelsFree (pMbCache->pCoeffLevel, "pMbCache->pCoeffLevel");
pMbCache->pCoeffLevel = NULL;
}
if (NULL != pMbCache->pMemPredMb) {
pMa->WelsFree (pMbCache->pMemPredMb, "pMbCache->pMemPredMb");
pMbCache->pMemPredMb = NULL;
}
if (NULL != pMbCache->pSkipMb) {
pMa->WelsFree (pMbCache->pSkipMb, "pMbCache->pSkipMb");
pMbCache->pSkipMb = NULL;
}
if (NULL != pMbCache->pMemPredBlk4) {
pMa->WelsFree (pMbCache->pMemPredBlk4, "pMbCache->pMemPredBlk4");
pMbCache->pMemPredBlk4 = NULL;
}
if (NULL != pMbCache->pBufferInterPredMe) {
pMa->WelsFree (pMbCache->pBufferInterPredMe, "pMbCache->pBufferInterPredMe");
pMbCache->pBufferInterPredMe = NULL;
}
if (NULL != pMbCache->pPrevIntra4x4PredModeFlag) {
pMa->WelsFree (pMbCache->pPrevIntra4x4PredModeFlag, "pMbCache->pPrevIntra4x4PredModeFlag");
pMbCache->pPrevIntra4x4PredModeFlag = NULL;
}
if (NULL != pMbCache->pRemIntra4x4PredModeFlag) {
pMa->WelsFree (pMbCache->pRemIntra4x4PredModeFlag, "pMbCache->pRemIntra4x4PredModeFlag");
pMbCache->pRemIntra4x4PredModeFlag = NULL;
}
if (NULL != pMbCache->pDct) {
pMa->WelsFree (pMbCache->pDct, "pMbCache->pDct");
pMbCache->pDct = NULL;
FreeSliceBuffer (pDq->sLayerInfo.pSliceInLayer, pDq->iMaxSliceNum, pMa, "pSliceInLayer");
for (; iIdx < MAX_THREADS_NUM; iIdx ++) {
FreeSliceBuffer (pDq->sSliceThreadInfo.pSliceInThread[iIdx],
pDq->sSliceThreadInfo.iMaxSliceNumInThread[iIdx],
pMa, "pSliceInLayer");
}
}
@ -957,22 +910,7 @@ void FreeDqLayer (SDqLayer*& pDq, CMemoryAlign* pMa) {
return;
}
if (NULL != pDq->sLayerInfo.pSliceInLayer) {
int32_t iSliceIdx = 0;
while (iSliceIdx < pDq->iMaxSliceNum) {
SSlice* pSlice = &pDq->sLayerInfo.pSliceInLayer[iSliceIdx];
FreeMbCache (&pSlice->sMbCacheInfo, pMa);
//slice bs buffer
if (NULL != pSlice->sSliceBs.pBs) {
pMa->WelsFree (pSlice->sSliceBs.pBs, "sSliceBs.pBs");
pSlice->sSliceBs.pBs = NULL;
}
++ iSliceIdx;
}
pMa->WelsFree (pDq->sLayerInfo.pSliceInLayer, "pSliceInLayer");
pDq->sLayerInfo.pSliceInLayer = NULL;
}
FreeSliceInLayer (pDq, pMa);
if (pDq->pNumSliceCodedOfPartition) {
pMa->WelsFree (pDq->pNumSliceCodedOfPartition, "pNumSliceCodedOfPartition");
@ -1165,47 +1103,138 @@ int32_t FindExistingPps (SWelsSPS* pSps, SSubsetSps* pSubsetSps, const bool kbUs
return INVALID_ID;
}
static inline int32_t InitpSliceInLayer (sWelsEncCtx** ppCtx, SDqLayer* pDqLayer, CMemoryAlign* pMa,
const int32_t iMaxSliceNum, const int32_t kiDlayerIndex) {
static inline int32_t InitSliceList (sWelsEncCtx** ppCtx,
SDqLayer* pDqLayer,
SSlice* pSliceList,
const int32_t kiMaxSliceNum,
const int32_t kiDlayerIndex,
CMemoryAlign* pMa) {
const int32_t kiMBWidth = pDqLayer->iMbWidth;
const int32_t kiMBHeight = pDqLayer->iMbHeight;
SSliceArgument* pSliceArgument = & (*ppCtx)->pSvcParam->sSpatialLayers[kiDlayerIndex].sSliceArgument;
int32_t iMaxSliceBufferSize = (*ppCtx)->iSliceBufferSize[kiDlayerIndex];
int32_t iSliceIdx = 0;
SliceModeEnum uiSliceMode = (*ppCtx)->pSvcParam->sSpatialLayers[kiDlayerIndex].sSliceArgument.uiSliceMode;
int32_t iRet = 0;
//SM_SINGLE_SLICE mode using single-thread bs writer pOut->sBsWrite
//even though multi-thread is on for other layers
bool bIndependenceBsBuffer = ((*ppCtx)->pSvcParam->iMultipleThreadIdc > 1 &&
SM_SINGLE_SLICE != uiSliceMode) ? true : false;
SM_SINGLE_SLICE != pSliceArgument->uiSliceMode) ? true : false;
if (iMaxSliceBufferSize <= 0) {
if (iMaxSliceBufferSize <= 0 || kiMBWidth <= 0 || kiMBHeight <= 0) {
return ENC_RETURN_UNEXPECTED;
}
while (iSliceIdx < iMaxSliceNum) {
SSlice* pSlice = &pDqLayer->sLayerInfo.pSliceInLayer[iSliceIdx];
while (iSliceIdx < kiMaxSliceNum) {
SSlice* pSlice = pSliceList + iSliceIdx;
if (NULL == pSlice)
return ENC_RETURN_MEMALLOCERR;
pSlice->uiSliceIdx = iSliceIdx;
pSlice->sSliceBs.uiSize = iMaxSliceBufferSize;
pSlice->sSliceBs.uiBsPos = 0;
if (bIndependenceBsBuffer) {
pSlice->pSliceBsa = &pSlice->sSliceBs.sBsWrite;
pSlice->sSliceBs.pBs = (uint8_t*)pMa->WelsMalloc (iMaxSliceBufferSize, "SliceBs");
if (NULL == pSlice->sSliceBs.pBs) {
return ENC_RETURN_MEMALLOCERR;
}
} else {
pSlice->pSliceBsa = & (*ppCtx)->pOut->sBsWrite;
pSlice->sSliceBs.pBs = NULL;
}
if (AllocMbCacheAligned (&pSlice->sMbCacheInfo, pMa)) {
FreeMemorySvc (ppCtx);
return ENC_RETURN_MEMALLOCERR;
}
iRet = InitSliceBsBuffer (pSlice,
& (*ppCtx)->pOut->sBsWrite,
bIndependenceBsBuffer,
iMaxSliceBufferSize,
pMa);
if (ENC_RETURN_SUCCESS != iRet)
return iRet;
iRet = InitSliceMBInfo (pSliceArgument, pSlice,
kiMBWidth, kiMBHeight,
pMa);
if (ENC_RETURN_SUCCESS != iRet)
return iRet;
iRet = AllocateSliceMBBuffer (pSlice, pMa);
if (ENC_RETURN_SUCCESS != iRet)
return iRet;
++ iSliceIdx;
}
return ENC_RETURN_SUCCESS;
}
static inline int32_t InitSliceThreadInfo (sWelsEncCtx** ppCtx,
SDqLayer* pDqLayer,
const int32_t kiDlayerIndex,
CMemoryAlign* pMa) {
SSliceThreadInfo* pSliceThreadInfo = &pDqLayer->sSliceThreadInfo;
int32_t iThreadNum = (*ppCtx)->pSvcParam->iMultipleThreadIdc;
int32_t iMaxSliceNumInThread = 0;
int32_t iIdx = 0;
int32_t iRet = 0;
assert (iThreadNum > 0);
iMaxSliceNumInThread = ((*ppCtx)->iMaxSliceCount / iThreadNum + 1) * 2;
iMaxSliceNumInThread = WELS_MIN ((*ppCtx)->iMaxSliceCount, (int) iMaxSliceNumInThread);
while (iIdx < iThreadNum) {
pSliceThreadInfo->iMaxSliceNumInThread[iIdx] = iMaxSliceNumInThread;
pSliceThreadInfo->iEncodedSliceNumInThread[iIdx] = 0;
pSliceThreadInfo->pSliceInThread[iIdx] = (SSlice*)pMa->WelsMallocz (sizeof (SSlice) *
iMaxSliceNumInThread, "pSliceInThread");
if(NULL == pSliceThreadInfo->pSliceInThread[iIdx])
return ENC_RETURN_MEMALLOCERR;
iRet = InitSliceList (ppCtx,
pDqLayer,
pSliceThreadInfo->pSliceInThread[iIdx],
iMaxSliceNumInThread,
kiDlayerIndex,
pMa);
if (ENC_RETURN_SUCCESS != iRet)
return iRet;
iIdx++;
}
for (; iIdx < MAX_THREADS_NUM; iIdx++) {
pSliceThreadInfo->iMaxSliceNumInThread[iIdx] = iMaxSliceNumInThread;
pSliceThreadInfo->iEncodedSliceNumInThread[iIdx] = 0;
pSliceThreadInfo->pSliceInThread[iIdx] = NULL;
}
return ENC_RETURN_SUCCESS;
}
static inline int32_t InitSliceInLayer (sWelsEncCtx** ppCtx,
SDqLayer* pDqLayer,
const int32_t kiDlayerIndex,
CMemoryAlign* pMa) {
//SWelsSvcCodingParam* pParam = (*ppCtx)->pSvcParam;
int32_t iRet = 0;
int32_t iMaxSliceNum = pDqLayer->iMaxSliceNum;
//if (pParam->iMultipleThreadIdc > 1) {
// to do, will add later, slice buffer allocated based on thread mode if() else ()
InitSliceThreadInfo (ppCtx,
pDqLayer,
kiDlayerIndex,
pMa);
if (ENC_RETURN_SUCCESS != iRet)
return iRet;
//} else {
pDqLayer->sLayerInfo.pSliceInLayer = (SSlice*)pMa->WelsMallocz (sizeof (SSlice) * iMaxSliceNum, "pSliceInLayer");
if(NULL == pDqLayer->sLayerInfo.pSliceInLayer)
return ENC_RETURN_MEMALLOCERR;
InitSliceList (ppCtx,
pDqLayer,
pDqLayer->sLayerInfo.pSliceInLayer,
iMaxSliceNum,
kiDlayerIndex,
pMa);
if (ENC_RETURN_SUCCESS != iRet)
return iRet;
//}
return ENC_RETURN_SUCCESS;
}
/*!
* \brief initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available
* \pParam pCtx sWelsEncCtx*
@ -1309,12 +1338,12 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
if (iMaxSliceNum < kiSliceNum)
iMaxSliceNum = kiSliceNum;
pDqLayer->iMaxSliceNum = iMaxSliceNum;
{
pDqLayer->sLayerInfo.pSliceInLayer = (SSlice*)pMa->WelsMallocz (sizeof (SSlice) * iMaxSliceNum, "pSliceInLayer");
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pDqLayer->sLayerInfo.pSliceInLayer), FreeDqLayer (pDqLayer, pMa))
int32_t iReturn = InitpSliceInLayer (ppCtx, pDqLayer, pMa, iMaxSliceNum, iDlayerIndex);
WELS_VERIFY_RETURN_PROC_IF (1, (ENC_RETURN_SUCCESS != iReturn), FreeDqLayer (pDqLayer, pMa))
iResult = InitSliceInLayer (ppCtx, pDqLayer, iDlayerIndex, pMa);
if (iResult) {
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "InitDqLayers(), InitSliceInLayer failed(%d)!", iResult);
FreeDqLayer (pDqLayer, pMa);
return iResult;
}
//deblocking parameters initialization
@ -3769,8 +3798,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
pCtx->iEncoderError = ENC_RETURN_SUCCESS;
pCtx->bCurFrameMarkedAsSceneLtr = false;
pFbi->iLayerNum = 0; // for initialization
pFbi->uiTimeStamp = GetTimestampForRc (pSrcPic->uiTimeStamp, pCtx->uiLastTimestamp,
pCtx->pSvcParam->sSpatialLayers[pCtx->pSvcParam->iSpatialLayerNum - 1].fFrameRate);
pFbi->uiTimeStamp = GetTimestampForRc (pSrcPic->uiTimeStamp, pCtx->uiLastTimestamp, pCtx->pSvcParam->sSpatialLayers[pCtx->pSvcParam->iSpatialLayerNum - 1].fFrameRate);
for (int32_t iNalIdx = 0; iNalIdx < MAX_LAYER_NUM_OF_FRAME; iNalIdx++) {
pFbi->sLayerInfo[iNalIdx].eFrameType = videoFrameTypeSkip;
}

View File

@ -271,6 +271,7 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara
assert (iThreadNum > 0);
iMaxSliceNumInThread = ((*ppCtx)->iMaxSliceCount / iThreadNum + 1) * 2;
iMaxSliceNumInThread = WELS_MIN ((*ppCtx)->iMaxSliceCount, (int) iMaxSliceNumInThread);
pSmt = (SSliceThreading*)pMa->WelsMalloc (sizeof (SSliceThreading), "SSliceThreading");
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pSmt), FreeMemorySvc (ppCtx))
@ -307,8 +308,6 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara
pSmt->pThreadPEncCtx[iIdx].pWelsPEncCtx = (void*) *ppCtx;
pSmt->pThreadPEncCtx[iIdx].iSliceIndex = iIdx;
pSmt->pThreadPEncCtx[iIdx].iThreadIndex = iIdx;
pSmt->iMaxSliceNumInThread[iIdx] = iMaxSliceNumInThread;
pSmt->iEncodedSliceNumInThread[iIdx] = 0;
pSmt->pThreadHandles[iIdx] = 0;
WelsSnprintf (name, SEM_NAME_MAX, "ee%d%s", iIdx, pSmt->eventNamespace);
@ -332,19 +331,10 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara
err = WelsEventOpen (&pSmt->pReadySliceCodingEvent[iIdx], name);
MT_TRACE_LOG (pLogCtx, WELS_LOG_INFO, "[MT] Open pReadySliceCodingEvent%d = 0x%p named(%s) ret%d err%d", iIdx,
(void*)pSmt->pReadySliceCodingEvent[iIdx], name, err, errno);
pSmt->pSliceInThread[iIdx] = (SSlice*)pMa->WelsMalloc (sizeof (SSlice)*iMaxSliceNumInThread, "pSmt->pSliceInThread");
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pSmt->pSliceInThread[iIdx]), FreeMemorySvc (ppCtx))
pSmt->piSliceIndexInThread[iIdx] = (int32_t *)pMa->WelsMalloc (iMaxSliceNumInThread, "pSmt->piSliceIndexInThread");
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pSmt->piSliceIndexInThread[iIdx]), FreeMemorySvc (ppCtx))
++ iIdx;
}
for (; iIdx < MAX_THREADS_NUM; iIdx++) {
pSmt->pThreadBsBuffer[iIdx] = NULL;
pSmt->pSliceInThread[iIdx] = NULL;
pSmt->piSliceIndexInThread[iIdx] = NULL;
}
WelsSnprintf (name, SEM_NAME_MAX, "scm%s", pSmt->eventNamespace);
@ -432,16 +422,6 @@ void ReleaseMtResource (sWelsEncCtx** ppCtx) {
pMa->WelsFree (pSmt->pThreadBsBuffer[i], "pSmt->pThreadBsBuffer");
pSmt->pThreadBsBuffer[i] = NULL;
}
if (pSmt->pSliceInThread[i]) {
pMa->WelsFree (pSmt->pSliceInThread[i], "pSmt->pSliceInThread");
pSmt->pSliceInThread[i] = NULL;
}
if (pSmt->piSliceIndexInThread[i]) {
pMa->WelsFree (pSmt->piSliceIndexInThread[i], "pSmt->piSliceIndexInThread");
pSmt->piSliceIndexInThread[i] = NULL;
}
}
memset (&pSmt->bThreadBsBufferUsage, 0, MAX_THREADS_NUM * sizeof (bool));

View File

@ -69,8 +69,6 @@ int32_t AssignMbMapSingleSlice (void* pMbMap, const int32_t kiCountMbNum, const
*/
int32_t AssignMbMapMultipleSlices (SDqLayer* pCurDq,const SSliceArgument* kpSliceArgument) {
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;
@ -82,9 +80,6 @@ int32_t AssignMbMapMultipleSlices (SDqLayer* pCurDq,const SSliceArgument* kpSlic
iSliceIdx = 0;
while (iSliceIdx < iSliceNum) {
const int32_t kiFirstMb = iSliceIdx * kiMbWidth;
SSliceHeaderExt* pSliceHeaderExt = &pSliceInLayer[iSliceIdx].sSliceHeaderExt;
pSliceInLayer[iSliceIdx].iCountMbNumInSlice = kiMbWidth;
pSliceHeaderExt->sSliceHeader.iFirstMbInSlice = kiFirstMb;
WelsSetMemMultiplebytes_c(pSliceSeg->pOverallMbMap + kiFirstMb, iSliceIdx,
kiMbWidth, sizeof(uint16_t));
++ iSliceIdx;
@ -102,9 +97,6 @@ int32_t AssignMbMapMultipleSlices (SDqLayer* pCurDq,const SSliceArgument* kpSlic
do {
const int32_t kiCurRunLength = kpSlicesAssignList[iSliceIdx];
int32_t iRunIdx = 0;
pSliceHeaderExt = &pSliceInLayer[iSliceIdx].sSliceHeaderExt;
pSliceHeaderExt->sSliceHeader.iFirstMbInSlice = iMbIdx;
pSliceInLayer[iSliceIdx].iCountMbNumInSlice = kiCurRunLength;
// due here need check validate mb_assign_map for input pData, can not use memset
do {
@ -116,16 +108,7 @@ int32_t AssignMbMapMultipleSlices (SDqLayer* pCurDq,const SSliceArgument* kpSlic
++ iSliceIdx;
} while (iSliceIdx < kiCountSliceNumInFrame && iMbIdx < kiCountNumMbInFrame);
} else if (SM_SIZELIMITED_SLICE == pSliceSeg->uiSliceMode) {
const int32_t kiMaxSliceNum = pSliceSeg->iMaxSliceNumConstraint;
const int32_t kiCountNumMbInFrame = pSliceSeg->iMbNumInFrame;
iSliceIdx = 0;
do {
pSliceHeaderExt = &pSliceInLayer[iSliceIdx].sSliceHeaderExt;
pSliceHeaderExt->sSliceHeader.iFirstMbInSlice = 0;
pSliceInLayer[iSliceIdx].iCountMbNumInSlice = kiCountNumMbInFrame;
iSliceIdx++;
} while (iSliceIdx < kiMaxSliceNum);
// do nothing,pSliceSeg->pOverallMbMap will be initial later
} else { // any else uiSliceMode?
assert (0);
}

View File

@ -89,7 +89,7 @@ void WelsSliceHeaderScalExtInit (SDqLayer* pCurLayer, SSlice* pSlice) {
void WelsSliceHeaderExtInit (sWelsEncCtx* pEncCtx, SDqLayer* pCurLayer, SSlice* pSlice) {
SSliceHeaderExt* pCurSliceExt = &pSlice->sSliceHeaderExt;
SSliceHeader* pCurSliceHeader = &pCurSliceExt->sSliceHeader;
SSpatialLayerInternal *pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
pCurSliceHeader->eSliceType = pEncCtx->eSliceType;
pCurSliceExt->bStoreRefBasePicFlag = false;
@ -138,7 +138,7 @@ void WelsSliceHeaderExtInit (sWelsEncCtx* pEncCtx, SDqLayer* pCurLayer, SSlice*
}
void UpdateMbNeighbor(SDqLayer* pCurDq, SMB* pMb, const int32_t kiMbWidth, uint16_t uiSliceIdc) {
void UpdateMbNeighbor (SDqLayer* pCurDq, SMB* pMb, const int32_t kiMbWidth, uint16_t uiSliceIdc) {
uint32_t uiNeighborAvailFlag = 0;
const int32_t kiMbXY = pMb->iMbXY;
const int32_t kiMbX = pMb->iMbX;
@ -298,7 +298,7 @@ void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCur
if (P_SLICE == pSliceHeader->eSliceType) {
BsWriteOneBit (pBs, pSliceHeader->bNumRefIdxActiveOverrideFlag);
if (pSliceHeader->bNumRefIdxActiveOverrideFlag) {
BsWriteUE (pBs, WELS_CLIP3(pSliceHeader->uiNumRefIdxL0Active - 1, 0, MAX_REF_PIC_COUNT));
BsWriteUE (pBs, WELS_CLIP3 (pSliceHeader->uiNumRefIdxL0Active - 1, 0, MAX_REF_PIC_COUNT));
}
}
@ -366,7 +366,7 @@ void WelsSliceHeaderExtWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* p
if (P_SLICE == pSliceHeader->eSliceType) {
BsWriteOneBit (pBs, pSliceHeader->bNumRefIdxActiveOverrideFlag);
if (pSliceHeader->bNumRefIdxActiveOverrideFlag) {
BsWriteUE (pBs, WELS_CLIP3(pSliceHeader->uiNumRefIdxL0Active - 1, 0, MAX_REF_PIC_COUNT));
BsWriteUE (pBs, WELS_CLIP3 (pSliceHeader->uiNumRefIdxL0Active - 1, 0, MAX_REF_PIC_COUNT));
}
}
@ -746,6 +746,163 @@ static const PWelsSliceHeaderWriteFunc g_pWelsWriteSliceHeader[2] = { // 0: for
WelsSliceHeaderExtWrite
};
//Allocate slice's MB cache buffer
int32_t AllocMbCacheAligned (SMbCache* pMbCache, CMemoryAlign* pMa) {
pMbCache->pCoeffLevel = (int16_t*)pMa->WelsMallocz (MB_COEFF_LIST_SIZE * sizeof (int16_t), "pMbCache->pCoeffLevel");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pCoeffLevel));
pMbCache->pMemPredMb = (uint8_t*)pMa->WelsMallocz (2 * 256 * sizeof (uint8_t), "pMbCache->pMemPredMb");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pMemPredMb));
pMbCache->pSkipMb = (uint8_t*)pMa->WelsMallocz (384 * sizeof (uint8_t), "pMbCache->pSkipMb");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pSkipMb));
pMbCache->pMemPredBlk4 = (uint8_t*)pMa->WelsMallocz (2 * 16 * sizeof (uint8_t), "pMbCache->pMemPredBlk4");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pMemPredBlk4));
pMbCache->pBufferInterPredMe = (uint8_t*)pMa->WelsMallocz (4 * 640 * sizeof (uint8_t), "pMbCache->pBufferInterPredMe");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pBufferInterPredMe));
pMbCache->pPrevIntra4x4PredModeFlag = (bool*)pMa->WelsMallocz (16 * sizeof (bool),
"pMbCache->pPrevIntra4x4PredModeFlag");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pPrevIntra4x4PredModeFlag));
pMbCache->pRemIntra4x4PredModeFlag = (int8_t*)pMa->WelsMallocz (16 * sizeof (int8_t),
"pMbCache->pRemIntra4x4PredModeFlag");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pRemIntra4x4PredModeFlag));
pMbCache->pDct = (SDCTCoeff*)pMa->WelsMallocz (sizeof (SDCTCoeff), "pMbCache->pDct");
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pDct));
return 0;
}
// Free slice's MB cache buffer
void FreeMbCache (SMbCache* pMbCache, CMemoryAlign* pMa) {
if (NULL != pMbCache->pCoeffLevel) {
pMa->WelsFree (pMbCache->pCoeffLevel, "pMbCache->pCoeffLevel");
pMbCache->pCoeffLevel = NULL;
}
if (NULL != pMbCache->pMemPredMb) {
pMa->WelsFree (pMbCache->pMemPredMb, "pMbCache->pMemPredMb");
pMbCache->pMemPredMb = NULL;
}
if (NULL != pMbCache->pSkipMb) {
pMa->WelsFree (pMbCache->pSkipMb, "pMbCache->pSkipMb");
pMbCache->pSkipMb = NULL;
}
if (NULL != pMbCache->pMemPredBlk4) {
pMa->WelsFree (pMbCache->pMemPredBlk4, "pMbCache->pMemPredBlk4");
pMbCache->pMemPredBlk4 = NULL;
}
if (NULL != pMbCache->pBufferInterPredMe) {
pMa->WelsFree (pMbCache->pBufferInterPredMe, "pMbCache->pBufferInterPredMe");
pMbCache->pBufferInterPredMe = NULL;
}
if (NULL != pMbCache->pPrevIntra4x4PredModeFlag) {
pMa->WelsFree (pMbCache->pPrevIntra4x4PredModeFlag, "pMbCache->pPrevIntra4x4PredModeFlag");
pMbCache->pPrevIntra4x4PredModeFlag = NULL;
}
if (NULL != pMbCache->pRemIntra4x4PredModeFlag) {
pMa->WelsFree (pMbCache->pRemIntra4x4PredModeFlag, "pMbCache->pRemIntra4x4PredModeFlag");
pMbCache->pRemIntra4x4PredModeFlag = NULL;
}
if (NULL != pMbCache->pDct) {
pMa->WelsFree (pMbCache->pDct, "pMbCache->pDct");
pMbCache->pDct = NULL;
}
}
//Initialize slice's MB info)
int32_t InitSliceMBInfo (SSliceArgument* pSliceArgument,
SSlice* pSlice,
const int32_t kiMBWidth,
const int32_t kiMBHeight,
CMemoryAlign* pMa) {
SSliceHeader* pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
const int32_t* kpSlicesAssignList = (int32_t*) & (pSliceArgument->uiSliceMbNum[0]);
const int32_t kiCountNumMbInFrame = kiMBWidth * kiMBHeight;
const int32_t kiSliceIdx = pSlice->uiSliceIdx;
int32_t iFirstMBInSlice = 0;
int32_t iMbNumInSlice = 0;
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 ||
SM_FIXEDSLCNUM_SLICE == pSliceArgument->uiSliceMode) {
int32_t iMbIdx = 0;
for (int i = 0; i < kiSliceIdx; i++) {
iMbIdx += kpSlicesAssignList[i];
}
if (iMbIdx >= kiCountNumMbInFrame)
return ENC_RETURN_UNEXPECTED;
iFirstMBInSlice = iMbIdx;
iMbNumInSlice = kpSlicesAssignList[kiSliceIdx];
} else if (SM_SIZELIMITED_SLICE == pSliceArgument->uiSliceMode) {
iFirstMBInSlice = 0;
iMbNumInSlice = kiCountNumMbInFrame;
} else { // any else uiSliceMode?
assert (0);
}
pSlice->iCountMbNumInSlice = iMbNumInSlice;
pSliceHeader->iFirstMbInSlice = iFirstMBInSlice;
return ENC_RETURN_SUCCESS;
}
//Allocate slice's MB info buffer
int32_t AllocateSliceMBBuffer (SSlice* pSlice, CMemoryAlign* pMa) {
if (AllocMbCacheAligned (&pSlice->sMbCacheInfo, pMa)) {
return ENC_RETURN_MEMALLOCERR;
}
return ENC_RETURN_SUCCESS;
}
// Initialize slice bs buffer info
int32_t InitSliceBsBuffer (SSlice* pSlice,
SBitStringAux* pBsWrite,
bool bIndependenceBsBuffer,
const int32_t iMaxSliceBufferSize,
CMemoryAlign* pMa) {
pSlice->sSliceBs.uiSize = iMaxSliceBufferSize;
pSlice->sSliceBs.uiBsPos = 0;
if (bIndependenceBsBuffer) {
pSlice->pSliceBsa = &pSlice->sSliceBs.sBsWrite;
pSlice->sSliceBs.pBs = (uint8_t*)pMa->WelsMalloc (iMaxSliceBufferSize, "SliceBs");
if (NULL == pSlice->sSliceBs.pBs) {
return ENC_RETURN_MEMALLOCERR;
}
} else {
pSlice->pSliceBsa = pBsWrite;
pSlice->sSliceBs.pBs = NULL;
}
return ENC_RETURN_SUCCESS;
}
//free slice bs buffer
void FreeSliceBuffer (SSlice*& pSliceList, const int32_t kiMaxSliceNum, CMemoryAlign* pMa, const char* kpTag) {
if (NULL != pSliceList) {
int32_t iSliceIdx = 0;
while (iSliceIdx < kiMaxSliceNum) {
SSlice* pSlice = &pSliceList[iSliceIdx];
FreeMbCache (&pSlice->sMbCacheInfo, pMa);
//slice bs buffer
if (NULL != pSlice->sSliceBs.pBs) {
pMa->WelsFree (pSlice->sSliceBs.pBs, "sSliceBs.pBs");
pSlice->sSliceBs.pBs = NULL;
}
++ iSliceIdx;
}
pMa->WelsFree (pSliceList, kpTag);
pSliceList = NULL;
}
}
int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const int32_t kiNalType) {
SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;