Merge pull request #2460 from sijchen/refactor_ref2

[Encoder] move strategy related pointer to class
This commit is contained in:
sijchen 2016-05-18 11:40:08 -07:00
commit 3fd490dbed
6 changed files with 138 additions and 37 deletions

View File

@ -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

View File

@ -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__

View File

@ -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;

View File

@ -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))

View File

@ -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;

View File

@ -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