Merge pull request #2421 from shihuade/MultiThread_V5.2_Pull_V2
refactor for slice buffer init/allocate/free
This commit is contained in:
commit
40e1a69fae
@ -90,11 +90,6 @@ uint8_t* pThreadBsBuffer[MAX_THREADS_NUM]; //actual memor
|
|||||||
bool bThreadBsBufferUsage[MAX_THREADS_NUM];
|
bool bThreadBsBufferUsage[MAX_THREADS_NUM];
|
||||||
WELS_MUTEX mutexThreadBsBufferUsage;
|
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;
|
} SSliceThreading;
|
||||||
|
|
||||||
#endif//MULTIPLE_THREADING_DEFINES_H__
|
#endif//MULTIPLE_THREADING_DEFINES_H__
|
||||||
|
@ -68,10 +68,17 @@ uint8_t uiFMEGoodFrameCount;
|
|||||||
int32_t iHighFreMbCount;
|
int32_t iHighFreMbCount;
|
||||||
} SFeatureSearchPreparation; //maintain only one
|
} 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 {
|
typedef struct TagLayerInfo {
|
||||||
SNalUnitHeaderExt sNalHeaderExt;
|
SNalUnitHeaderExt sNalHeaderExt;
|
||||||
SSlice*
|
SSlice* pSliceInLayer; // Here SSlice identify to Frame on concept, [iSliceIndex],
|
||||||
pSliceInLayer;// Here SSlice identify to Frame on concept, [iSliceIndex], need memory block external side for MT
|
// may need extend list size for sliceMode=SM_SIZELIMITED_SLICE
|
||||||
SSubsetSps* pSubsetSpsP; // current pSubsetSps used, memory alloc in external
|
SSubsetSps* pSubsetSpsP; // current pSubsetSps used, memory alloc in external
|
||||||
SWelsSPS* pSpsP; // current pSps based avc used, memory alloc in external
|
SWelsSPS* pSpsP; // current pSps based avc used, memory alloc in external
|
||||||
SWelsPPS* pPpsP; // current pPps used
|
SWelsPPS* pPpsP; // current pPps used
|
||||||
@ -79,6 +86,8 @@ SWelsPPS* pPpsP; // current pPps used
|
|||||||
/* Layer Representation */
|
/* Layer Representation */
|
||||||
struct TagDqLayer {
|
struct TagDqLayer {
|
||||||
SLayerInfo sLayerInfo;
|
SLayerInfo sLayerInfo;
|
||||||
|
SSliceThreadInfo sSliceThreadInfo;
|
||||||
|
SSlice** ppSliceInLayer;
|
||||||
SSliceCtx sSliceEncCtx; // current slice context
|
SSliceCtx sSliceEncCtx; // current slice context
|
||||||
uint8_t* pCsData[3]; // pointer to reconstructed picture pData
|
uint8_t* pCsData[3]; // pointer to reconstructed picture pData
|
||||||
int32_t iCsStride[3]; // Cs stride
|
int32_t iCsStride[3]; // Cs stride
|
||||||
|
@ -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 WelsISliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice); // for intra non-dynamic slice
|
||||||
int32_t WelsISliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice); // for intra 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 WelsCodePSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);
|
||||||
int32_t WelsCodePOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);
|
int32_t WelsCodePOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);
|
||||||
|
|
||||||
|
@ -894,61 +894,14 @@ int32_t InitMbListD (sWelsEncCtx** ppCtx) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
void FreeSliceInLayer (SDqLayer* pDq, CMemoryAlign* pMa) {
|
||||||
|
int32_t iIdx = 0;
|
||||||
|
|
||||||
int32_t AllocMbCacheAligned (SMbCache* pMbCache, CMemoryAlign* pMa) {
|
FreeSliceBuffer (pDq->sLayerInfo.pSliceInLayer, pDq->iMaxSliceNum, pMa, "pSliceInLayer");
|
||||||
pMbCache->pCoeffLevel = (int16_t*)pMa->WelsMallocz (MB_COEFF_LIST_SIZE * sizeof (int16_t), "pMbCache->pCoeffLevel");
|
for (; iIdx < MAX_THREADS_NUM; iIdx ++) {
|
||||||
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pCoeffLevel));
|
FreeSliceBuffer (pDq->sSliceThreadInfo.pSliceInThread[iIdx],
|
||||||
pMbCache->pMemPredMb = (uint8_t*)pMa->WelsMallocz (2 * 256 * sizeof (uint8_t), "pMbCache->pMemPredMb");
|
pDq->sSliceThreadInfo.iMaxSliceNumInThread[iIdx],
|
||||||
WELS_VERIFY_RETURN_IF (1, (NULL == pMbCache->pMemPredMb));
|
pMa, "pSliceInLayer");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,22 +910,7 @@ void FreeDqLayer (SDqLayer*& pDq, CMemoryAlign* pMa) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != pDq->sLayerInfo.pSliceInLayer) {
|
FreeSliceInLayer (pDq, pMa);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pDq->pNumSliceCodedOfPartition) {
|
if (pDq->pNumSliceCodedOfPartition) {
|
||||||
pMa->WelsFree (pDq->pNumSliceCodedOfPartition, "pNumSliceCodedOfPartition");
|
pMa->WelsFree (pDq->pNumSliceCodedOfPartition, "pNumSliceCodedOfPartition");
|
||||||
@ -1165,47 +1103,138 @@ int32_t FindExistingPps (SWelsSPS* pSps, SSubsetSps* pSubsetSps, const bool kbUs
|
|||||||
return INVALID_ID;
|
return INVALID_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t InitpSliceInLayer (sWelsEncCtx** ppCtx, SDqLayer* pDqLayer, CMemoryAlign* pMa,
|
static inline int32_t InitSliceList (sWelsEncCtx** ppCtx,
|
||||||
const int32_t iMaxSliceNum, const int32_t kiDlayerIndex) {
|
SDqLayer* pDqLayer,
|
||||||
int32_t iMaxSliceBufferSize = (*ppCtx)->iSliceBufferSize[kiDlayerIndex];
|
SSlice* pSliceList,
|
||||||
int32_t iSliceIdx = 0;
|
const int32_t kiMaxSliceNum,
|
||||||
SliceModeEnum uiSliceMode = (*ppCtx)->pSvcParam->sSpatialLayers[kiDlayerIndex].sSliceArgument.uiSliceMode;
|
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;
|
||||||
|
int32_t iRet = 0;
|
||||||
|
|
||||||
//SM_SINGLE_SLICE mode using single-thread bs writer pOut->sBsWrite
|
//SM_SINGLE_SLICE mode using single-thread bs writer pOut->sBsWrite
|
||||||
//even though multi-thread is on for other layers
|
//even though multi-thread is on for other layers
|
||||||
bool bIndependenceBsBuffer = ((*ppCtx)->pSvcParam->iMultipleThreadIdc > 1 &&
|
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;
|
return ENC_RETURN_UNEXPECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (iSliceIdx < iMaxSliceNum) {
|
while (iSliceIdx < kiMaxSliceNum) {
|
||||||
SSlice* pSlice = &pDqLayer->sLayerInfo.pSliceInLayer[iSliceIdx];
|
SSlice* pSlice = pSliceList + iSliceIdx;
|
||||||
|
if (NULL == pSlice)
|
||||||
|
return ENC_RETURN_MEMALLOCERR;
|
||||||
|
|
||||||
pSlice->uiSliceIdx = iSliceIdx;
|
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)) {
|
iRet = InitSliceBsBuffer (pSlice,
|
||||||
FreeMemorySvc (ppCtx);
|
& (*ppCtx)->pOut->sBsWrite,
|
||||||
return ENC_RETURN_MEMALLOCERR;
|
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;
|
++ iSliceIdx;
|
||||||
}
|
}
|
||||||
return ENC_RETURN_SUCCESS;
|
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
|
* \brief initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available
|
||||||
* \pParam pCtx sWelsEncCtx*
|
* \pParam pCtx sWelsEncCtx*
|
||||||
@ -1309,12 +1338,12 @@ static inline int32_t InitDqLayers (sWelsEncCtx** ppCtx, SExistingParasetList* p
|
|||||||
if (iMaxSliceNum < kiSliceNum)
|
if (iMaxSliceNum < kiSliceNum)
|
||||||
iMaxSliceNum = kiSliceNum;
|
iMaxSliceNum = kiSliceNum;
|
||||||
pDqLayer->iMaxSliceNum = iMaxSliceNum;
|
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);
|
iResult = InitSliceInLayer (ppCtx, pDqLayer, iDlayerIndex, pMa);
|
||||||
WELS_VERIFY_RETURN_PROC_IF (1, (ENC_RETURN_SUCCESS != iReturn), FreeDqLayer (pDqLayer, pMa))
|
if (iResult) {
|
||||||
|
WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_WARNING, "InitDqLayers(), InitSliceInLayer failed(%d)!", iResult);
|
||||||
|
FreeDqLayer (pDqLayer, pMa);
|
||||||
|
return iResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
//deblocking parameters initialization
|
//deblocking parameters initialization
|
||||||
@ -3769,8 +3798,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour
|
|||||||
pCtx->iEncoderError = ENC_RETURN_SUCCESS;
|
pCtx->iEncoderError = ENC_RETURN_SUCCESS;
|
||||||
pCtx->bCurFrameMarkedAsSceneLtr = false;
|
pCtx->bCurFrameMarkedAsSceneLtr = false;
|
||||||
pFbi->iLayerNum = 0; // for initialization
|
pFbi->iLayerNum = 0; // for initialization
|
||||||
pFbi->uiTimeStamp = GetTimestampForRc (pSrcPic->uiTimeStamp, pCtx->uiLastTimestamp,
|
pFbi->uiTimeStamp = GetTimestampForRc (pSrcPic->uiTimeStamp, pCtx->uiLastTimestamp, pCtx->pSvcParam->sSpatialLayers[pCtx->pSvcParam->iSpatialLayerNum - 1].fFrameRate);
|
||||||
pCtx->pSvcParam->sSpatialLayers[pCtx->pSvcParam->iSpatialLayerNum - 1].fFrameRate);
|
|
||||||
for (int32_t iNalIdx = 0; iNalIdx < MAX_LAYER_NUM_OF_FRAME; iNalIdx++) {
|
for (int32_t iNalIdx = 0; iNalIdx < MAX_LAYER_NUM_OF_FRAME; iNalIdx++) {
|
||||||
pFbi->sLayerInfo[iNalIdx].eFrameType = videoFrameTypeSkip;
|
pFbi->sLayerInfo[iNalIdx].eFrameType = videoFrameTypeSkip;
|
||||||
}
|
}
|
||||||
|
@ -271,6 +271,7 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pCodingPara
|
|||||||
|
|
||||||
assert (iThreadNum > 0);
|
assert (iThreadNum > 0);
|
||||||
iMaxSliceNumInThread = ((*ppCtx)->iMaxSliceCount / iThreadNum + 1) * 2;
|
iMaxSliceNumInThread = ((*ppCtx)->iMaxSliceCount / iThreadNum + 1) * 2;
|
||||||
|
iMaxSliceNumInThread = WELS_MIN ((*ppCtx)->iMaxSliceCount, (int) iMaxSliceNumInThread);
|
||||||
|
|
||||||
pSmt = (SSliceThreading*)pMa->WelsMalloc (sizeof (SSliceThreading), "SSliceThreading");
|
pSmt = (SSliceThreading*)pMa->WelsMalloc (sizeof (SSliceThreading), "SSliceThreading");
|
||||||
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pSmt), FreeMemorySvc (ppCtx))
|
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].pWelsPEncCtx = (void*) *ppCtx;
|
||||||
pSmt->pThreadPEncCtx[iIdx].iSliceIndex = iIdx;
|
pSmt->pThreadPEncCtx[iIdx].iSliceIndex = iIdx;
|
||||||
pSmt->pThreadPEncCtx[iIdx].iThreadIndex = iIdx;
|
pSmt->pThreadPEncCtx[iIdx].iThreadIndex = iIdx;
|
||||||
pSmt->iMaxSliceNumInThread[iIdx] = iMaxSliceNumInThread;
|
|
||||||
pSmt->iEncodedSliceNumInThread[iIdx] = 0;
|
|
||||||
pSmt->pThreadHandles[iIdx] = 0;
|
pSmt->pThreadHandles[iIdx] = 0;
|
||||||
|
|
||||||
WelsSnprintf (name, SEM_NAME_MAX, "ee%d%s", iIdx, pSmt->eventNamespace);
|
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);
|
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,
|
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);
|
(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;
|
++ iIdx;
|
||||||
}
|
}
|
||||||
for (; iIdx < MAX_THREADS_NUM; iIdx++) {
|
for (; iIdx < MAX_THREADS_NUM; iIdx++) {
|
||||||
pSmt->pThreadBsBuffer[iIdx] = NULL;
|
pSmt->pThreadBsBuffer[iIdx] = NULL;
|
||||||
pSmt->pSliceInThread[iIdx] = NULL;
|
|
||||||
pSmt->piSliceIndexInThread[iIdx] = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WelsSnprintf (name, SEM_NAME_MAX, "scm%s", pSmt->eventNamespace);
|
WelsSnprintf (name, SEM_NAME_MAX, "scm%s", pSmt->eventNamespace);
|
||||||
@ -432,16 +422,6 @@ void ReleaseMtResource (sWelsEncCtx** ppCtx) {
|
|||||||
pMa->WelsFree (pSmt->pThreadBsBuffer[i], "pSmt->pThreadBsBuffer");
|
pMa->WelsFree (pSmt->pThreadBsBuffer[i], "pSmt->pThreadBsBuffer");
|
||||||
pSmt->pThreadBsBuffer[i] = NULL;
|
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));
|
memset (&pSmt->bThreadBsBufferUsage, 0, MAX_THREADS_NUM * sizeof (bool));
|
||||||
|
|
||||||
|
@ -68,10 +68,8 @@ int32_t AssignMbMapSingleSlice (void* pMbMap, const int32_t kiCountMbNum, const
|
|||||||
* \return 0 - successful; none 0 - failed
|
* \return 0 - successful; none 0 - failed
|
||||||
*/
|
*/
|
||||||
int32_t AssignMbMapMultipleSlices (SDqLayer* pCurDq,const SSliceArgument* kpSliceArgument) {
|
int32_t AssignMbMapMultipleSlices (SDqLayer* pCurDq,const SSliceArgument* kpSliceArgument) {
|
||||||
SSliceCtx* pSliceSeg = &pCurDq->sSliceEncCtx;
|
SSliceCtx* pSliceSeg = &pCurDq->sSliceEncCtx;
|
||||||
SSlice* pSliceInLayer = pCurDq->sLayerInfo.pSliceInLayer;
|
int32_t iSliceIdx = 0;
|
||||||
SSliceHeaderExt* pSliceHeaderExt = NULL;
|
|
||||||
int32_t iSliceIdx = 0;
|
|
||||||
if (NULL == pSliceSeg || SM_SINGLE_SLICE == pSliceSeg->uiSliceMode)
|
if (NULL == pSliceSeg || SM_SINGLE_SLICE == pSliceSeg->uiSliceMode)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -82,9 +80,6 @@ int32_t AssignMbMapMultipleSlices (SDqLayer* pCurDq,const SSliceArgument* kpSlic
|
|||||||
iSliceIdx = 0;
|
iSliceIdx = 0;
|
||||||
while (iSliceIdx < iSliceNum) {
|
while (iSliceIdx < iSliceNum) {
|
||||||
const int32_t kiFirstMb = iSliceIdx * kiMbWidth;
|
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,
|
WelsSetMemMultiplebytes_c(pSliceSeg->pOverallMbMap + kiFirstMb, iSliceIdx,
|
||||||
kiMbWidth, sizeof(uint16_t));
|
kiMbWidth, sizeof(uint16_t));
|
||||||
++ iSliceIdx;
|
++ iSliceIdx;
|
||||||
@ -102,9 +97,6 @@ int32_t AssignMbMapMultipleSlices (SDqLayer* pCurDq,const SSliceArgument* kpSlic
|
|||||||
do {
|
do {
|
||||||
const int32_t kiCurRunLength = kpSlicesAssignList[iSliceIdx];
|
const int32_t kiCurRunLength = kpSlicesAssignList[iSliceIdx];
|
||||||
int32_t iRunIdx = 0;
|
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
|
// due here need check validate mb_assign_map for input pData, can not use memset
|
||||||
do {
|
do {
|
||||||
@ -116,16 +108,7 @@ int32_t AssignMbMapMultipleSlices (SDqLayer* pCurDq,const SSliceArgument* kpSlic
|
|||||||
++ iSliceIdx;
|
++ iSliceIdx;
|
||||||
} while (iSliceIdx < kiCountSliceNumInFrame && iMbIdx < kiCountNumMbInFrame);
|
} while (iSliceIdx < kiCountSliceNumInFrame && iMbIdx < kiCountNumMbInFrame);
|
||||||
} else if (SM_SIZELIMITED_SLICE == pSliceSeg->uiSliceMode) {
|
} else if (SM_SIZELIMITED_SLICE == pSliceSeg->uiSliceMode) {
|
||||||
const int32_t kiMaxSliceNum = pSliceSeg->iMaxSliceNumConstraint;
|
// do nothing,pSliceSeg->pOverallMbMap will be initial later
|
||||||
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);
|
|
||||||
} else { // any else uiSliceMode?
|
} else { // any else uiSliceMode?
|
||||||
assert (0);
|
assert (0);
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ void WelsSliceHeaderScalExtInit (SDqLayer* pCurLayer, SSlice* pSlice) {
|
|||||||
void WelsSliceHeaderExtInit (sWelsEncCtx* pEncCtx, SDqLayer* pCurLayer, SSlice* pSlice) {
|
void WelsSliceHeaderExtInit (sWelsEncCtx* pEncCtx, SDqLayer* pCurLayer, SSlice* pSlice) {
|
||||||
SSliceHeaderExt* pCurSliceExt = &pSlice->sSliceHeaderExt;
|
SSliceHeaderExt* pCurSliceExt = &pSlice->sSliceHeaderExt;
|
||||||
SSliceHeader* pCurSliceHeader = &pCurSliceExt->sSliceHeader;
|
SSliceHeader* pCurSliceHeader = &pCurSliceExt->sSliceHeader;
|
||||||
SSpatialLayerInternal *pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
|
SSpatialLayerInternal* pParamInternal = &pEncCtx->pSvcParam->sDependencyLayers[pEncCtx->uiDependencyId];
|
||||||
pCurSliceHeader->eSliceType = pEncCtx->eSliceType;
|
pCurSliceHeader->eSliceType = pEncCtx->eSliceType;
|
||||||
|
|
||||||
pCurSliceExt->bStoreRefBasePicFlag = false;
|
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;
|
uint32_t uiNeighborAvailFlag = 0;
|
||||||
const int32_t kiMbXY = pMb->iMbXY;
|
const int32_t kiMbXY = pMb->iMbXY;
|
||||||
const int32_t kiMbX = pMb->iMbX;
|
const int32_t kiMbX = pMb->iMbX;
|
||||||
@ -298,7 +298,7 @@ void WelsSliceHeaderWrite (sWelsEncCtx* pCtx, SBitStringAux* pBs, SDqLayer* pCur
|
|||||||
if (P_SLICE == pSliceHeader->eSliceType) {
|
if (P_SLICE == pSliceHeader->eSliceType) {
|
||||||
BsWriteOneBit (pBs, pSliceHeader->bNumRefIdxActiveOverrideFlag);
|
BsWriteOneBit (pBs, pSliceHeader->bNumRefIdxActiveOverrideFlag);
|
||||||
if (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) {
|
if (P_SLICE == pSliceHeader->eSliceType) {
|
||||||
BsWriteOneBit (pBs, pSliceHeader->bNumRefIdxActiveOverrideFlag);
|
BsWriteOneBit (pBs, pSliceHeader->bNumRefIdxActiveOverrideFlag);
|
||||||
if (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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,7 +521,7 @@ void UpdateQpForOverflow (SMB* pCurMb, uint8_t kuiChromaQpIndexOffset) {
|
|||||||
//second. lower than highest Dependency Layer, and for every Dependency Layer with one quality layer(single layer)
|
//second. lower than highest Dependency Layer, and for every Dependency Layer with one quality layer(single layer)
|
||||||
int32_t WelsISliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + encoding
|
int32_t WelsISliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + encoding
|
||||||
SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
|
SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
|
||||||
SMbCache* pMbCache = &pSlice->sMbCacheInfo;
|
SMbCache* pMbCache = &pSlice->sMbCacheInfo;
|
||||||
SSliceHeaderExt* pSliceHdExt = &pSlice->sSliceHeaderExt;
|
SSliceHeaderExt* pSliceHdExt = &pSlice->sSliceHeaderExt;
|
||||||
SMB* pMbList = pCurLayer->sMbDataP;
|
SMB* pMbList = pCurLayer->sMbDataP;
|
||||||
SMB* pCurMb = NULL;
|
SMB* pCurMb = NULL;
|
||||||
@ -746,6 +746,163 @@ static const PWelsSliceHeaderWriteFunc g_pWelsWriteSliceHeader[2] = { // 0: for
|
|||||||
WelsSliceHeaderExtWrite
|
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) {
|
int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const int32_t kiNalType) {
|
||||||
SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
|
SDqLayer* pCurLayer = pEncCtx->pCurDqLayer;
|
||||||
@ -753,8 +910,8 @@ int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const
|
|||||||
SSlice* pCurSlice = &pCurLayer->sLayerInfo.pSliceInLayer[kiSliceIdx];
|
SSlice* pCurSlice = &pCurLayer->sLayerInfo.pSliceInLayer[kiSliceIdx];
|
||||||
SBitStringAux* pBs = pCurSlice->pSliceBsa;
|
SBitStringAux* pBs = pCurSlice->pSliceBsa;
|
||||||
const int32_t kiDynamicSliceFlag = (pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId].sSliceArgument.uiSliceMode
|
const int32_t kiDynamicSliceFlag = (pEncCtx->pSvcParam->sSpatialLayers[pEncCtx->uiDependencyId].sSliceArgument.uiSliceMode
|
||||||
==
|
==
|
||||||
SM_SIZELIMITED_SLICE);
|
SM_SIZELIMITED_SLICE);
|
||||||
|
|
||||||
assert (kiSliceIdx == (int) pCurSlice->uiSliceIdx);
|
assert (kiSliceIdx == (int) pCurSlice->uiSliceIdx);
|
||||||
|
|
||||||
@ -805,7 +962,7 @@ void UpdateMbNeighbourInfoForNextSlice (SDqLayer* pCurDq,
|
|||||||
int32_t iIdx = kiFirstMbIdxOfNextSlice;
|
int32_t iIdx = kiFirstMbIdxOfNextSlice;
|
||||||
int32_t iNextSliceFirstMbIdxRowStart = ((kiFirstMbIdxOfNextSlice % kiMbWidth) ? 1 : 0);
|
int32_t iNextSliceFirstMbIdxRowStart = ((kiFirstMbIdxOfNextSlice % kiMbWidth) ? 1 : 0);
|
||||||
int32_t iCountMbUpdate = kiMbWidth +
|
int32_t iCountMbUpdate = kiMbWidth +
|
||||||
iNextSliceFirstMbIdxRowStart; //need to update MB(iMbXY+1) to MB(iMbXY+1+row) in common case
|
iNextSliceFirstMbIdxRowStart; //need to update MB(iMbXY+1) to MB(iMbXY+1+row) in common case
|
||||||
const int32_t kiEndMbNeedUpdate = kiFirstMbIdxOfNextSlice + iCountMbUpdate;
|
const int32_t kiEndMbNeedUpdate = kiFirstMbIdxOfNextSlice + iCountMbUpdate;
|
||||||
SMB* pMb = &pMbList[iIdx];
|
SMB* pMb = &pMbList[iIdx];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user