diff --git a/codec/encoder/core/inc/slice_multi_threading.h b/codec/encoder/core/inc/slice_multi_threading.h index 48c33a05..12348874 100644 --- a/codec/encoder/core/inc/slice_multi_threading.h +++ b/codec/encoder/core/inc/slice_multi_threading.h @@ -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); diff --git a/codec/encoder/core/src/slice_multi_threading.cpp b/codec/encoder/core/src/slice_multi_threading.cpp index 7f298609..b1060f2f 100644 --- a/codec/encoder/core/src/slice_multi_threading.cpp +++ b/codec/encoder/core/src/slice_multi_threading.cpp @@ -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; diff --git a/test/api/encode_decode_api_test.cpp b/test/api/encode_decode_api_test.cpp index 51501879..168b768b 100644 --- a/test/api/encode_decode_api_test.cpp +++ b/test/api/encode_decode_api_test.cpp @@ -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, public ::EncodeDecodeTestAPIBase { @@ -3494,9 +3496,9 @@ class EncodeTestAPI : public ::testing::TestWithParam, 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 (¶m_);