Merge pull request #2460 from sijchen/refactor_ref2
[Encoder] move strategy related pointer to class
This commit is contained in:
commit
3fd490dbed
@ -62,6 +62,9 @@
|
||||
|
||||
namespace WelsEnc {
|
||||
|
||||
class IWelsTaskManage;
|
||||
class IWelsReferenceStrategy;
|
||||
|
||||
/*
|
||||
* reference list for each quality layer in SVC
|
||||
*/
|
||||
@ -135,6 +138,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
|
||||
|
@ -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__
|
||||
|
@ -286,12 +286,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;
|
||||
|
@ -222,8 +222,6 @@ int32_t InitFunctionPointers (sWelsEncCtx* pEncCtx, SWelsSvcCodingParam* pParam,
|
||||
|
||||
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))
|
||||
|
@ -1754,6 +1754,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<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 @@ 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");
|
||||
@ -3700,8 +3707,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);
|
||||
@ -3710,7 +3717,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);
|
||||
@ -3964,7 +3971,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;
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user