ref: 3fd490dbedae851ef5996d9867980eec8958683d
parent: 7188e50acf45189f242b83aa7d5595a3e0145c53
parent: 1ac02f3002332d365069c3e6aaae02789f1ca73d
author: sijchen <[email protected]>
date: Wed May 18 07:40:08 EDT 2016
Merge pull request #2460 from sijchen/refactor_ref2 [Encoder] move strategy related pointer to class
--- a/codec/encoder/core/inc/encoder_context.h
+++ b/codec/encoder/core/inc/encoder_context.h
@@ -62,6 +62,9 @@
namespace WelsEnc {
+class IWelsTaskManage;
+class IWelsReferenceStrategy;
+
/*
* reference list for each quality layer in SVC
*/
@@ -135,6 +138,7 @@
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
--- a/codec/encoder/core/inc/ref_list_mgr_svc.h
+++ b/codec/encoder/core/inc/ref_list_mgr_svc.h
@@ -93,10 +93,56 @@
*/
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__
--- a/codec/encoder/core/inc/wels_func_ptr_def.h
+++ b/codec/encoder/core/inc/wels_func_ptr_def.h
@@ -286,12 +286,6 @@
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;
--- a/codec/encoder/core/src/encoder.cpp
+++ b/codec/encoder/core/src/encoder.cpp
@@ -222,8 +222,6 @@
InitFillNeighborCacheInterFunc (pFuncList, pParam->bEnableBackgroundDetection);
- InitRefListMgrFunc (pFuncList, pParam->bEnableLongTermReference, bScreenContent);
-
pFuncList->pParametersetStrategy = IWelsParametersetStrategy::CreateParametersetStrategy (pParam->eSpsPpsIdStrategy,
pParam->bSimulcastAVC, pParam->iSpatialLayerNum);
WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, (NULL == pFuncList->pParametersetStrategy))
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -1754,6 +1754,9 @@
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<int8_t*>
(pMa->WelsMallocz (iCountMaxMbNum * INTRA_4x4_MODE_NUM, "pIntra4x4PredModeBlocks"));
WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pIntra4x4PredModeBlocks), FreeMemorySvc (ppCtx))
@@ -1942,6 +1945,10 @@
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");
@@ -3700,8 +3707,8 @@
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);
@@ -3710,7 +3717,7 @@
break;
}
if (pCtx->eSliceType != I_SLICE) {
- pCtx->pFuncList->pAfterBuildRefList (pCtx);
+ pCtx->pReferenceStrategy->AfterBuildRefList ();
}
#ifdef LONG_TERM_REF_DUMP
DumpRef (pCtx);
@@ -3964,7 +3971,7 @@
// 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;
--- a/codec/encoder/core/src/ref_list_mgr_svc.cpp
+++ b/codec/encoder/core/src/ref_list_mgr_svc.cpp
@@ -426,7 +426,7 @@
pCtx->pVaa->uiMarkLongTermPicIdx = 0;
}
}
- pCtx->pFuncList->pEndofUpdateRefList (pCtx);
+ pCtx->pReferenceStrategy->EndofUpdateRefList();
return true;
}
@@ -793,9 +793,10 @@
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 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