Merge pull request #2059 from sijchen/mt52

[Encoder] multi-threading refactoring
This commit is contained in:
HaiboZhu 2015-08-05 09:28:13 +08:00
commit 47dcacee83
3 changed files with 54 additions and 80 deletions

View File

@ -70,8 +70,6 @@ int32_t RequestMtResource (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pParam, con
void ReleaseMtResource (sWelsEncCtx** ppCtx);
int32_t AppendSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, const int32_t kiSliceCount);
int32_t WriteSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, uint8_t* pFrameBsBuffer, const int32_t iSliceIdx,
int32_t& iSliceSize);
#if !defined(_WIN32)
WELS_THREAD_ROUTINE_TYPE UpdateMbListThreadProc (void* arg);

View File

@ -560,9 +560,9 @@ int32_t AppendSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, const int32
if (!kbIsDynamicSlicingMode) {
pSliceBs = &pCtx->pSliceBs[0];
iLayerSize = pSliceBs->uiBsPos; // assign with base pSlice first
iSliceIdx = 1; // pSlice 0 bs has been written to pFrameBs yet by now, so uiSliceIdx base should be 1
iSliceIdx = 0;
iNalIdxBase = pLbi->iNalCount = 0;
while (iSliceIdx < iSliceCount) {
++ pSliceBs;
if (pSliceBs != NULL && pSliceBs->uiBsPos > 0) {
int32_t iNalIdx = 0;
const int32_t iCountNal = pSliceBs->iNalIndex;
@ -571,11 +571,13 @@ int32_t AppendSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, const int32
assert (pSliceBs->bSliceCodedFlag);
#endif//MT_DEBUG_BS_WR
memmove (pCtx->pFrameBs + pCtx->iPosBsBuffer, pSliceBs->pBs, pSliceBs->uiBsPos); // confirmed_safe_unsafe_usage
pCtx->iPosBsBuffer += pSliceBs->uiBsPos;
iLayerSize += pSliceBs->uiBsPos;
if (iSliceIdx > 0) {
// pSlice 0 bs has been written to pFrameBs yet by now, so uiSliceIdx base should be 1
memmove (pCtx->pFrameBs + pCtx->iPosBsBuffer, pSliceBs->pBs, pSliceBs->uiBsPos); // confirmed_safe_unsafe_usage
pCtx->iPosBsBuffer += pSliceBs->uiBsPos;
iLayerSize += pSliceBs->uiBsPos;
}
while (iNalIdx < iCountNal) {
pLbi->pNalLengthInByte[iNalIdxBase + iNalIdx] = pSliceBs->iNalLen[iNalIdx];
++ iNalIdx;
@ -584,6 +586,7 @@ int32_t AppendSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, const int32
iNalIdxBase += iCountNal;
}
++ iSliceIdx;
++ pSliceBs;
}
} else { // for SM_DYN_SLICE
const int32_t kiPartitionCnt = iSliceCount;
@ -629,58 +632,18 @@ int32_t AppendSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, const int32
return iLayerSize;
}
int32_t WriteSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, uint8_t* pFrameBsBuffer, const int32_t iSliceIdx,
int32_t& iSliceSize) {
int32_t WriteSliceBs (sWelsEncCtx* pCtx, uint8_t* pDst,
int32_t* pNalLen,
int32_t iTotalLeftLength,
const int32_t iSliceIdx,
int32_t& iSliceSize) {
SWelsSliceBs* pSliceBs = &pCtx->pSliceBs[iSliceIdx];
SNalUnitHeaderExt* pNalHdrExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt;
uint8_t* pDst = pFrameBsBuffer;
const int32_t kiNalCnt = pSliceBs->iNalIndex;
int32_t iNalIdx = 0;
int32_t iNalSize = 0;
const int32_t iFirstSlice = (iSliceIdx == 0);
int32_t iNalBase = iFirstSlice ? 0 : pLbi->iNalCount;
int32_t iReturn = ENC_RETURN_SUCCESS;
const int32_t kiWrittenLength = pCtx->iPosBsBuffer;
iSliceSize = 0;
while (iNalIdx < kiNalCnt) {
iNalSize = 0;
iReturn = WelsEncodeNal (&pSliceBs->sNalList[iNalIdx], pNalHdrExt, pCtx->iFrameBsSize - kiWrittenLength - iSliceSize,
pDst, &iNalSize);
WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
iSliceSize += iNalSize;
pDst += iNalSize;
pLbi->pNalLengthInByte[iNalBase + iNalIdx] = iNalSize;
++ iNalIdx;
}
pSliceBs->uiBsPos = iSliceSize;
if (iFirstSlice) {
// pBsBuffer has been updated at coding_slice_0_in_encoder_mother_thread()
pLbi->uiLayerType = VIDEO_CODING_LAYER;
pLbi->uiSpatialId = pNalHdrExt->uiDependencyId;
pLbi->uiTemporalId = pNalHdrExt->uiTemporalId;
pLbi->uiQualityId = 0;
pLbi->iNalCount = kiNalCnt;
} else {
pLbi->iNalCount += kiNalCnt;
}
return ENC_RETURN_SUCCESS;
}
int32_t WriteSliceBs (sWelsEncCtx* pCtx, uint8_t* pSliceBsBuf, const int32_t iSliceIdx, int32_t& iSliceSize) {
SWelsSliceBs* pSliceBs = &pCtx->pSliceBs[iSliceIdx];
SNalUnitHeaderExt* pNalHdrExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt;
uint8_t* pDst = pSliceBsBuf;
int32_t* pNalLen = &pSliceBs->iNalLen[0];
const int32_t kiNalCnt = pSliceBs->iNalIndex;
int32_t iNalIdx = 0;
int32_t iNalSize = 0;
int32_t iReturn = ENC_RETURN_SUCCESS;
const int32_t kiWrittenLength = (int32_t) (pSliceBs->sBsWrite.pCurBuf - pSliceBs->sBsWrite.pStartBuf);
iSliceSize = 0;
assert (kiNalCnt <= 2);
if (kiNalCnt > 2)
@ -688,7 +651,7 @@ int32_t WriteSliceBs (sWelsEncCtx* pCtx, uint8_t* pSliceBsBuf, const int32_t iSl
while (iNalIdx < kiNalCnt) {
iNalSize = 0;
iReturn = WelsEncodeNal (&pSliceBs->sNalList[iNalIdx], pNalHdrExt, pSliceBs->uiSize - kiWrittenLength - iSliceSize,
iReturn = WelsEncodeNal (&pSliceBs->sNalList[iNalIdx], pNalHdrExt, iTotalLeftLength - iSliceSize,
pDst, &iNalSize);
WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
pNalLen[iNalIdx] = iNalSize;
@ -793,31 +756,28 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
iReturn = WelsCodeOneSlice (pEncPEncCtx, iSliceIdx, eNalType);
if (ENC_RETURN_SUCCESS != iReturn) {
uiThrdRet = iReturn;
WELS_THREAD_SIGNAL_AND_BREAK(pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent,
iEventIdx);
WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent,
iEventIdx);
}
WelsUnloadNalForSlice (pSliceBs);
int32_t iLeftBufferSize = (iSliceIdx > 0) ?
(pSliceBs->uiSize - (int32_t) (pSliceBs->sBsWrite.pCurBuf - pSliceBs->sBsWrite.pStartBuf))
: (pEncPEncCtx->iFrameBsSize - pEncPEncCtx->iPosBsBuffer);
iReturn = WriteSliceBs (pEncPEncCtx, pSliceBs->pBs,
&pSliceBs->iNalLen[0],
iLeftBufferSize,
iSliceIdx, iSliceSize);
if (ENC_RETURN_SUCCESS != iReturn) {
uiThrdRet = iReturn;
WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent,
iEventIdx);
}
if (0 == iSliceIdx) {
pLbi->pBsBuf = pEncPEncCtx->pFrameBs + pEncPEncCtx->iPosBsBuffer;
iReturn = WriteSliceToFrameBs (pEncPEncCtx, pLbi, pLbi->pBsBuf, iSliceIdx, iSliceSize);
if (ENC_RETURN_SUCCESS != iReturn) {
uiThrdRet = iReturn;
WELS_THREAD_SIGNAL_AND_BREAK(pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent,
iEventIdx);
}
pEncPEncCtx->iPosBsBuffer += iSliceSize;
} else {
iReturn = WriteSliceBs (pEncPEncCtx, pSliceBs->pBs, iSliceIdx, iSliceSize);
if (ENC_RETURN_SUCCESS != iReturn) {
uiThrdRet = iReturn;
WELS_THREAD_SIGNAL_AND_BREAK(pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent,
iEventIdx);
}
}
pEncPEncCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (pCurDq, pEncPEncCtx->pFuncList, iSliceIdx);
@ -909,10 +869,11 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
WelsUnloadNalForSlice (pSliceBs);
if (0 == kiPartitionId) {
if (0 == iSliceIdx)
pLbi->pBsBuf = pEncPEncCtx->pFrameBs + pEncPEncCtx->iPosBsBuffer;
iReturn = WriteSliceToFrameBs (pEncPEncCtx, pLbi, pEncPEncCtx->pFrameBs + pEncPEncCtx->iPosBsBuffer, iSliceIdx,
iSliceSize);
iReturn = WriteSliceBs (pEncPEncCtx, pLbi->pBsBuf,
&pLbi->pNalLengthInByte[pLbi->iNalCount],
pEncPEncCtx->iFrameBsSize - pEncPEncCtx->iPosBsBuffer,
iSliceIdx, iSliceSize);
pLbi->iNalCount += pSliceBs->iNalIndex;
if (ENC_RETURN_SUCCESS != iReturn) {
uiThrdRet = iReturn;
WELS_THREAD_SIGNAL_AND_BREAK(pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
@ -921,7 +882,9 @@ WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) {
}
pEncPEncCtx->iPosBsBuffer += iSliceSize;
} else {
iReturn = WriteSliceBs (pEncPEncCtx, pSliceBs->pBs, iSliceIdx, iSliceSize);
iReturn = WriteSliceBs (pEncPEncCtx, pSliceBs->pBs, &pSliceBs->iNalLen[0],
pSliceBs->uiSize - (int32_t) (pSliceBs->sBsWrite.pCurBuf - pSliceBs->sBsWrite.pStartBuf),
iSliceIdx, iSliceSize);
if (ENC_RETURN_SUCCESS != iReturn) {
uiThrdRet = iReturn;
WELS_THREAD_SIGNAL_AND_BREAK(pEncPEncCtx->pSliceThreading->pSliceCodedEvent,
@ -1030,6 +993,14 @@ int32_t FiredSliceThreads (sWelsEncCtx* pCtx, SSliceThreadPrivateData* pPriData,
}
}
pLbi->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
pLbi->uiLayerType = VIDEO_CODING_LAYER;
pLbi->uiSpatialId = pCtx->uiDependencyId;
pLbi->uiTemporalId = pCtx->uiTemporalId;
pLbi->uiQualityId = 0;
pLbi->iNalCount = 0;
pCtx->pSliceBs[0].pBs = pLbi->pBsBuf;
iIdx = 0;
while (iIdx < kiEventCnt) {
pPriData[iIdx].pLayerBs = pLbi;

View File

@ -3474,6 +3474,8 @@ static const EncodeOptionParam kOptionParamArray[] = {
{false, true, false, 30, 104, 416, 44, SM_DYN_SLICE, 500, 7.5, 2, ""},
{false, true, false, 30, 16, 16, 2, SM_DYN_SLICE, 500, 7.5, 3, ""},
{false, true, false, 30, 32, 16, 2, SM_DYN_SLICE, 500, 7.5, 3, ""},
{false, false, true, 30, 600, 460, 1, SM_FIXEDSLCNUM_SLICE, 0, 15.0, 4, ""},
{false, false, true, 30, 600, 460, 1, SM_AUTO_SLICE, 0, 15.0, 4, ""},
};
class EncodeTestAPI : public ::testing::TestWithParam<EncodeOptionParam>, public ::EncodeDecodeTestAPIBase {
@ -3494,9 +3496,9 @@ class EncodeTestAPI : public ::testing::TestWithParam<EncodeOptionParam>, public
}
int rv = encoder_->EncodeFrame (&EncPic, &info);
if (0 == iCheckTypeIndex)
ASSERT_TRUE (rv == cmResultSuccess);
ASSERT_TRUE (rv == cmResultSuccess) << "rv=" << rv;
else if (1 == iCheckTypeIndex)
ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnkonwReason);
ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnkonwReason) << "rv=" << rv;
}
};
@ -3525,6 +3527,9 @@ TEST_P (EncodeTestAPI, SetEncOptionSize) {
param_.sSpatialLayers[0].iVideoHeight = p.iHeight;
param_.sSpatialLayers[0].fFrameRate = p.fFramerate;
param_.sSpatialLayers[0].sSliceCfg.uiSliceMode = p.eSliceMode;
if (SM_AUTO_SLICE == p.eSliceMode || SM_FIXEDSLCNUM_SLICE == p.eSliceMode ) {
param_.sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum = 8;
}
encoder_->Uninitialize();
int rv = encoder_->InitializeExt (&param_);