ref: 9aafb779ebf22b50156f531809a7da6927512632
parent: 6b503843ec8ae27185180089365dd252e647ac7e
author: Sijia Chen <sijchen@cisco.com>
date: Mon Aug 3 17:42:47 EDT 2015
1, refactor to remove similar function (WriteSliceToFrameBs is removed) 2, use slice-level variable in child-thread function so there can be a better independency in child-thread function 3, add two more test cases
--- a/codec/encoder/core/inc/slice_multi_threading.h
+++ b/codec/encoder/core/inc/slice_multi_threading.h
@@ -70,8 +70,6 @@
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);
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -560,9 +560,9 @@
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 @@
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;
+ 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;
-
+ iLayerSize += pSliceBs->uiBsPos;
+ }
while (iNalIdx < iCountNal) {
pLbi->pNalLengthInByte[iNalIdxBase + iNalIdx] = pSliceBs->iNalLen[iNalIdx];
++ iNalIdx;
@@ -584,6 +586,7 @@
iNalIdxBase += iCountNal;
}
++ iSliceIdx;
+ ++ pSliceBs;
}
} else { // for SM_DYN_SLICE
const int32_t kiPartitionCnt = iSliceCount;
@@ -629,58 +632,18 @@
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 @@
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 @@
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 @@
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 @@
}
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,
@@ -1029,6 +992,14 @@
iEndMbIdx = iFirstMbIdx;
}
}
+
+ 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) {
--- a/test/api/encode_decode_api_test.cpp
+++ b/test/api/encode_decode_api_test.cpp
@@ -3474,6 +3474,8 @@
{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 @@
}
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 @@
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 (¶m_);