shithub: openh264

Download patch

ref: 00747540fbb1c2ec0488886579aa556a71f62aa6
parent: f623aa318de8d9697fc0e30cf8f4c503020ee286
author: sijchen <sijchen@cisco.com>
date: Mon May 16 06:55:13 EDT 2016

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,7 @@
 namespace WelsEnc {
 
 class IWelsTaskManage;
+class IWelsReferenceStrategy;
 /*
  *  reference list for each quality layer in SVC
  */
@@ -135,6 +136,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
@@ -284,12 +284,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
@@ -221,8 +221,6 @@
 
   InitFillNeighborCacheInterFunc (pFuncList, pParam->bEnableBackgroundDetection);
 
-  InitRefListMgrFunc (pFuncList, pParam->bEnableLongTermReference, bScreenContent);
-
   return iReturn;
 }
 
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -1983,6 +1983,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))
@@ -2171,6 +2174,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");
@@ -4013,8 +4020,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);
@@ -4023,7 +4030,7 @@
       break;
     }
     if (pCtx->eSliceType != I_SLICE) {
-      pCtx->pFuncList->pAfterBuildRefList (pCtx);
+      pCtx->pReferenceStrategy->AfterBuildRefList ();
     }
 #ifdef LONG_TERM_REF_DUMP
     DumpRef (pCtx);
@@ -4277,7 +4284,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