From 00747540fbb1c2ec0488886579aa556a71f62aa6 Mon Sep 17 00:00:00 2001 From: sijchen Date: Mon, 16 May 2016 10:55:13 -0700 Subject: [PATCH] move strategy related pointer to class --- codec/encoder/core/inc/encoder_context.h | 2 + codec/encoder/core/inc/ref_list_mgr_svc.h | 50 ++++++++++- codec/encoder/core/inc/wels_func_ptr_def.h | 6 -- codec/encoder/core/src/encoder.cpp | 2 - codec/encoder/core/src/encoder_ext.cpp | 15 +++- codec/encoder/core/src/ref_list_mgr_svc.cpp | 98 ++++++++++++++++----- 6 files changed, 136 insertions(+), 37 deletions(-) diff --git a/codec/encoder/core/inc/encoder_context.h b/codec/encoder/core/inc/encoder_context.h index 9ec1c2c0..4d604785 100644 --- a/codec/encoder/core/inc/encoder_context.h +++ b/codec/encoder/core/inc/encoder_context.h @@ -62,6 +62,7 @@ namespace WelsEnc { class IWelsTaskManage; +class IWelsReferenceStrategy; /* * reference list for each quality layer in SVC */ @@ -135,6 +136,7 @@ typedef struct TagWelsEncCtx { SSliceThreading* pSliceThreading; IWelsTaskManage* pTaskManage; //was planning to put it under CWelsH264SVCEncoder but it may be updated (lock/no lock) when param is changed + IWelsReferenceStrategy* pReferenceStrategy; // pointers SPicture* pEncPic; // pointer to current picture to be encoded diff --git a/codec/encoder/core/inc/ref_list_mgr_svc.h b/codec/encoder/core/inc/ref_list_mgr_svc.h index f66976d3..ad82e7e0 100644 --- a/codec/encoder/core/inc/ref_list_mgr_svc.h +++ b/codec/encoder/core/inc/ref_list_mgr_svc.h @@ -93,10 +93,56 @@ bool CheckCurMarkFrameNumUsed (sWelsEncCtx* pCtx); */ void WelsMarkPic (sWelsEncCtx* pCtx); -void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, const bool bEnableLongTermReference, const bool bScreenContent); - #ifdef LONG_TERM_REF_DUMP void DumpRef (sWelsEncCtx* ctx); #endif + +class IWelsReferenceStrategy { + public: + IWelsReferenceStrategy() {}; + virtual ~IWelsReferenceStrategy() { }; + + static IWelsReferenceStrategy* CreateReferenceStrategy (sWelsEncCtx* pCtx, const EUsageType keUsageType, + const bool kbLtrEnabled); + virtual bool BuildRefList (const int32_t iPOC, int32_t iBestLtrRefIdx) = 0; + virtual void MarkPic() = 0; + virtual bool UpdateRefList() = 0; + virtual void EndofUpdateRefList() = 0; + virtual void AfterBuildRefList() = 0; + + protected: + virtual void Init (sWelsEncCtx* pCtx) = 0; +}; + +class CWelsReference_TemporalLayer : public IWelsReferenceStrategy { + public: + virtual bool BuildRefList (const int32_t iPOC, int32_t iBestLtrRefIdx); + virtual void MarkPic(); + virtual bool UpdateRefList(); + virtual void EndofUpdateRefList(); + virtual void AfterBuildRefList(); + + void Init (sWelsEncCtx* pCtx); + protected: + sWelsEncCtx* m_pEncoderCtx; + +}; + +class CWelsReference_Screen : public CWelsReference_TemporalLayer { + public: + virtual bool BuildRefList (const int32_t iPOC, int32_t iBestLtrRefIdx); + virtual void MarkPic(); + virtual bool UpdateRefList(); + virtual void EndofUpdateRefList(); + virtual void AfterBuildRefList(); +}; + +class CWelsReference_LosslessWithLtr : public CWelsReference_Screen { + public: + virtual bool BuildRefList (const int32_t iPOC, int32_t iBestLtrRefIdx); + virtual void MarkPic(); + virtual bool UpdateRefList(); + virtual void EndofUpdateRefList(); +}; } #endif//REFERENCE_PICTURE_LIST_MANAGEMENT_SVC_H__ diff --git a/codec/encoder/core/inc/wels_func_ptr_def.h b/codec/encoder/core/inc/wels_func_ptr_def.h index 4724d441..24ddbe78 100644 --- a/codec/encoder/core/inc/wels_func_ptr_def.h +++ b/codec/encoder/core/inc/wels_func_ptr_def.h @@ -284,12 +284,6 @@ struct TagWelsFuncPointerList { PSetMemoryZero pfSetMemZeroSize64Aligned16; // for size is times of 64, and address is align to 16 PSetMemoryZero pfSetMemZeroSize64; // for size is times of 64, and don't know address is align to 16 or not - PBuildRefListFunc pBuildRefList; - PMarkPicFunc pMarkPic; - PUpdateRefListFunc pUpdateRefList; - PEndofUpdateRefListFunc pEndofUpdateRefList; - PAfterBuildRefListFunc pAfterBuildRefList; - PCavlcParamCalFunc pfCavlcParamCal; PWelsSpatialWriteMbSyn pfWelsSpatialWriteMbSyn; PStashMBStatus pfStashMBStatus; diff --git a/codec/encoder/core/src/encoder.cpp b/codec/encoder/core/src/encoder.cpp index c21f792c..d49ef80d 100644 --- a/codec/encoder/core/src/encoder.cpp +++ b/codec/encoder/core/src/encoder.cpp @@ -221,8 +221,6 @@ int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam, InitFillNeighborCacheInterFunc (pFuncList, pParam->bEnableBackgroundDetection); - InitRefListMgrFunc (pFuncList, pParam->bEnableLongTermReference, bScreenContent); - return iReturn; } diff --git a/codec/encoder/core/src/encoder_ext.cpp b/codec/encoder/core/src/encoder_ext.cpp index 7bd246f8..797134f2 100644 --- a/codec/encoder/core/src/encoder_ext.cpp +++ b/codec/encoder/core/src/encoder_ext.cpp @@ -1983,6 +1983,9 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx, SExistingParasetList* pExistingPa return 1; } + (*ppCtx)->pReferenceStrategy = IWelsReferenceStrategy::CreateReferenceStrategy((*ppCtx), pParam->iUsageType, pParam->bEnableLongTermReference); + WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pReferenceStrategy), FreeMemorySvc (ppCtx)) + (*ppCtx)->pIntra4x4PredModeBlocks = static_cast (pMa->WelsMallocz (iCountMaxMbNum * INTRA_4x4_MODE_NUM, "pIntra4x4PredModeBlocks")); WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pIntra4x4PredModeBlocks), FreeMemorySvc (ppCtx)) @@ -2171,6 +2174,10 @@ void FreeMemorySvc (sWelsEncCtx** ppCtx) { if (pParam != NULL && pParam->iMultipleThreadIdc > 1) ReleaseMtResource (ppCtx); + if (NULL != pCtx->pReferenceStrategy) { + WELS_DELETE_OP(pCtx->pReferenceStrategy); + } + // frame bitstream pBuffer if (NULL != pCtx->pFrameBs) { pMa->WelsFree (pCtx->pFrameBs, "pFrameBs"); @@ -4013,8 +4020,8 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour WelsInitCurrentLayer (pCtx, iCurWidth, iCurHeight); - pCtx->pFuncList->pMarkPic (pCtx); - if (!pCtx->pFuncList->pBuildRefList (pCtx, pParamInternal->iPOC, 0)) { + pCtx->pReferenceStrategy->MarkPic (); + if (!pCtx->pReferenceStrategy->BuildRefList (pParamInternal->iPOC, 0)) { WelsLog (pLogCtx, WELS_LOG_WARNING, "WelsEncoderEncodeExt(), WelsBuildRefList failed for P frames, pCtx->iNumRef0= %d. ForceCodingIDR!", pCtx->iNumRef0); @@ -4023,7 +4030,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour break; } if (pCtx->eSliceType != I_SLICE) { - pCtx->pFuncList->pAfterBuildRefList (pCtx); + pCtx->pReferenceStrategy->AfterBuildRefList (); } #ifdef LONG_TERM_REF_DUMP DumpRef (pCtx); @@ -4277,7 +4284,7 @@ int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSour // reference picture list update if (eNalRefIdc != NRI_PRI_LOWEST) { - if (!pCtx->pFuncList->pUpdateRefList (pCtx)) { + if (!pCtx->pReferenceStrategy->UpdateRefList ()) { WelsLog (pLogCtx, WELS_LOG_WARNING, "WelsEncoderEncodeExt(), WelsUpdateRefList failed. ForceCodingIDR!"); //the above is to set the next frame to be IDR pCtx->iEncoderError = ENC_RETURN_CORRECTED; diff --git a/codec/encoder/core/src/ref_list_mgr_svc.cpp b/codec/encoder/core/src/ref_list_mgr_svc.cpp index 68a0538d..2093d6cd 100644 --- a/codec/encoder/core/src/ref_list_mgr_svc.cpp +++ b/codec/encoder/core/src/ref_list_mgr_svc.cpp @@ -426,7 +426,7 @@ bool WelsUpdateRefList (sWelsEncCtx* pCtx) { pCtx->pVaa->uiMarkLongTermPicIdx = 0; } } - pCtx->pFuncList->pEndofUpdateRefList (pCtx); + pCtx->pReferenceStrategy->EndofUpdateRefList(); return true; } @@ -793,9 +793,10 @@ bool WelsUpdateRefListScreen (sWelsEncCtx* pCtx) { pCtx->pVaa->uiValidLongTermPicIdx = 0; } - pCtx->pFuncList->pEndofUpdateRefList (pCtx); + pCtx->pReferenceStrategy->EndofUpdateRefList(); return true; } + bool WelsBuildRefListScreen (sWelsEncCtx* pCtx, const int32_t iPOC, int32_t iBestLtrRefIdx) { SRefList* pRefList = pCtx->ppRefPicListExt[pCtx->uiDependencyId]; SWelsSvcCodingParam* pParam = pCtx->pSvcParam; @@ -993,31 +994,82 @@ void WelsMarkPicScreen (sWelsEncCtx* pCtx) { void DoNothing (sWelsEncCtx* pointer) { } -void InitRefListMgrFunc (SWelsFuncPtrList* pFuncList, const bool bWithLtr, const bool bScreenContent) { - bool bLosslessScreenRefSelectionWithLtr = bWithLtr && bScreenContent; - if (bLosslessScreenRefSelectionWithLtr) { - pFuncList->pBuildRefList = WelsBuildRefListScreen; - pFuncList->pMarkPic = WelsMarkPicScreen; - pFuncList->pUpdateRefList = WelsUpdateRefListScreen; - pFuncList->pEndofUpdateRefList = UpdateSrcPicList; - } else { - pFuncList->pBuildRefList = WelsBuildRefList; - pFuncList->pMarkPic = WelsMarkPic; - pFuncList->pUpdateRefList = WelsUpdateRefList; - pFuncList->pEndofUpdateRefList = PrefetchNextBuffer; - } - pFuncList->pAfterBuildRefList = DoNothing; - if (bScreenContent) { - if (bLosslessScreenRefSelectionWithLtr) { - pFuncList->pEndofUpdateRefList = UpdateSrcPicListLosslessScreenRefSelectionWithLtr; +IWelsReferenceStrategy* IWelsReferenceStrategy::CreateReferenceStrategy (sWelsEncCtx* pCtx, + const EUsageType keUsageType, + const bool kbLtrEnabled) { + + IWelsReferenceStrategy* pReferenceStrategy = NULL; + switch (keUsageType) { + case SCREEN_CONTENT_REAL_TIME: + if (kbLtrEnabled) { + pReferenceStrategy = WELS_NEW_OP (CWelsReference_LosslessWithLtr(), + CWelsReference_LosslessWithLtr); } else { - pFuncList->pEndofUpdateRefList = UpdateSrcPicList; - pFuncList->pAfterBuildRefList = UpdateBlockStatic; + pReferenceStrategy = WELS_NEW_OP (CWelsReference_Screen(), + CWelsReference_Screen); } - } else { - pFuncList->pEndofUpdateRefList = PrefetchNextBuffer; + WELS_VERIFY_RETURN_IF (NULL, NULL == pReferenceStrategy) + break; + case CAMERA_VIDEO_REAL_TIME: + case CAMERA_VIDEO_NON_REAL_TIME: + default: + pReferenceStrategy = WELS_NEW_OP (CWelsReference_TemporalLayer(), + CWelsReference_TemporalLayer); + WELS_VERIFY_RETURN_IF (NULL, NULL == pReferenceStrategy) + break; } + pReferenceStrategy->Init (pCtx); + return pReferenceStrategy; +} + +void CWelsReference_TemporalLayer::Init (sWelsEncCtx* pCtx) { + m_pEncoderCtx = pCtx; +} + +bool CWelsReference_TemporalLayer::BuildRefList (const int32_t iPOC, int32_t iBestLtrRefIdx) { + return WelsBuildRefList (m_pEncoderCtx, iPOC, iBestLtrRefIdx); +} +void CWelsReference_TemporalLayer::MarkPic() { + WelsMarkPic (m_pEncoderCtx); +} +bool CWelsReference_TemporalLayer::UpdateRefList() { + return WelsUpdateRefList (m_pEncoderCtx); +} +void CWelsReference_TemporalLayer::EndofUpdateRefList() { + PrefetchNextBuffer (m_pEncoderCtx); +} +void CWelsReference_TemporalLayer::AfterBuildRefList() { + DoNothing (m_pEncoderCtx); +} + +bool CWelsReference_Screen::BuildRefList (const int32_t iPOC, int32_t iBestLtrRefIdx) { + return WelsBuildRefList (m_pEncoderCtx, iPOC, iBestLtrRefIdx); +} +void CWelsReference_Screen::MarkPic() { + WelsMarkPic (m_pEncoderCtx); +} +bool CWelsReference_Screen::UpdateRefList() { + return WelsUpdateRefList (m_pEncoderCtx); +} +void CWelsReference_Screen::EndofUpdateRefList() { + UpdateSrcPicList (m_pEncoderCtx); +} +void CWelsReference_Screen::AfterBuildRefList() { + UpdateBlockStatic (m_pEncoderCtx); +} + +bool CWelsReference_LosslessWithLtr::BuildRefList (const int32_t iPOC, int32_t iBestLtrRefIdx) { + return WelsBuildRefListScreen (m_pEncoderCtx, iPOC, iBestLtrRefIdx); +} +void CWelsReference_LosslessWithLtr::MarkPic() { + WelsMarkPicScreen (m_pEncoderCtx); +} +bool CWelsReference_LosslessWithLtr::UpdateRefList() { + return WelsUpdateRefListScreen (m_pEncoderCtx); +} +void CWelsReference_LosslessWithLtr::EndofUpdateRefList() { + UpdateSrcPicListLosslessScreenRefSelectionWithLtr (m_pEncoderCtx); } } // namespace WelsEnc