shithub: openh264

Download patch

ref: 684c42536dffb826e70d6ea527d0c07baa8efb85
parent: 4fc144b69855c19b92b545f005bcf3e6a2b5da74
parent: 2f041c7a4bdcba443d770d8e512c641d1fc39773
author: huili2 <huili2@cisco.com>
date: Fri Sep 5 09:32:52 EDT 2014

Merge pull request #1330 from ruil2/delivery_status

modify delivery status interface

--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -183,7 +183,7 @@
 typedef struct {
   bool   bEnableLongTermReference; // 1: on, 0: off
   int	   iLTRRefNum;
-}SLTRConfig;
+} SLTRConfig;
 typedef struct {
   unsigned int
   uiSliceMbNum[MAX_SLICES_NUM_TMP];  //here we use a tmp fixed value since MAX_SLICES_NUM is not defined here and its definition may be changed;
@@ -428,9 +428,9 @@
 } SLevelInfo;
 
 typedef struct TagDeliveryStatus {
-  int iDropNum;      //the number of video frames that are dropped continuously before delivery to encoder, which is used by screen content.
-  int iDropFrameType; // the frame type that is dropped
-  int iDropFrameSize; // the frame size that is dropped
+  bool bDeliveryFlag;  //0: the previous frame isn't delivered,1: the previous frame is delivered
+  int iDropFrameType; // the frame type that is dropped; reserved
+  int iDropFrameSize; // the frame size that is dropped; reserved
 } SDeliveryStatus;
 
 typedef struct TagDecoderCapability {
--- a/codec/encoder/core/inc/encoder_context.h
+++ b/codec/encoder/core/inc/encoder_context.h
@@ -64,165 +64,165 @@
  *	reference list for each quality layer in SVC
  */
 typedef struct TagRefList {
-SPicture*					pShortRefList[1 + MAX_SHORT_REF_COUNT]; // reference list 0 - int16_t
-SPicture*					pLongRefList[1 + MAX_REF_PIC_COUNT];	// reference list 1 - int32_t
-SPicture*					pNextBuffer;
-SPicture*					pRef[1 + MAX_REF_PIC_COUNT];	// plus 1 for swap intend
-uint8_t						uiShortRefCount;
-uint8_t						uiLongRefCount;	// dependend on pRef pic module
+  SPicture*					pShortRefList[1 + MAX_SHORT_REF_COUNT]; // reference list 0 - int16_t
+  SPicture*					pLongRefList[1 + MAX_REF_PIC_COUNT];	// reference list 1 - int32_t
+  SPicture*					pNextBuffer;
+  SPicture*					pRef[1 + MAX_REF_PIC_COUNT];	// plus 1 for swap intend
+  uint8_t						uiShortRefCount;
+  uint8_t						uiLongRefCount;	// dependend on pRef pic module
 } SRefList;
 
 typedef struct TagLTRState {
 // LTR mark feedback
-uint32_t		    		uiLtrMarkState;	// LTR mark state, indicate whether there is a LTR mark feedback unsolved
-int32_t						iLtrMarkFbFrameNum;// the unsolved LTR mark feedback, the marked iFrameNum feedback from decoder
+  uint32_t		    		uiLtrMarkState;	// LTR mark state, indicate whether there is a LTR mark feedback unsolved
+  int32_t						iLtrMarkFbFrameNum;// the unsolved LTR mark feedback, the marked iFrameNum feedback from decoder
 
 // LTR used as recovery reference
-int32_t						iLastRecoverFrameNum; // reserve the last LTR or IDR recover iFrameNum
-int32_t
-iLastCorFrameNumDec; // reserved the last correct position in decoder side, use to select valid LTR to recover or to decide the LTR mark validation
-int32_t
-iCurFrameNumInDec; // current iFrameNum in decoder side, use to select valid LTR to recover or to decide the LTR mark validation
+  int32_t						iLastRecoverFrameNum; // reserve the last LTR or IDR recover iFrameNum
+  int32_t
+  iLastCorFrameNumDec; // reserved the last correct position in decoder side, use to select valid LTR to recover or to decide the LTR mark validation
+  int32_t
+  iCurFrameNumInDec; // current iFrameNum in decoder side, use to select valid LTR to recover or to decide the LTR mark validation
 
 // LTR mark
-int32_t						iLTRMarkMode; // direct mark or delay mark
-int32_t						iLTRMarkSuccessNum; //successful marked num, for mark mode switch
-int32_t						iCurLtrIdx;// current int32_t term reference index to mark
-int32_t						iLastLtrIdx[MAX_TEMPORAL_LAYER_NUM];
-int32_t						iSceneLtrIdx;// related to Scene LTR, used by screen content
+  int32_t						iLTRMarkMode; // direct mark or delay mark
+  int32_t						iLTRMarkSuccessNum; //successful marked num, for mark mode switch
+  int32_t						iCurLtrIdx;// current int32_t term reference index to mark
+  int32_t						iLastLtrIdx[MAX_TEMPORAL_LAYER_NUM];
+  int32_t						iSceneLtrIdx;// related to Scene LTR, used by screen content
 
-uint32_t					uiLtrMarkInterval;// the interval from the last int32_t term pRef mark
+  uint32_t					uiLtrMarkInterval;// the interval from the last int32_t term pRef mark
 
-bool						bLTRMarkingFlag;	//decide whether current frame marked as LTR
-bool						bLTRMarkEnable; //when LTR is confirmed and the interval is no smaller than the marking period
-bool						bReceivedT0LostFlag;	// indicate whether a t0 lost feedback is recieved, for LTR recovery
+  bool						bLTRMarkingFlag;	//decide whether current frame marked as LTR
+  bool						bLTRMarkEnable; //when LTR is confirmed and the interval is no smaller than the marking period
+  bool						bReceivedT0LostFlag;	// indicate whether a t0 lost feedback is recieved, for LTR recovery
 } SLTRState;
 
 typedef struct TagSpatialPicIndex {
-SPicture*	pSrc;	// I420 based and after color space converted
-int32_t		iDid;	// dependency id
+  SPicture*	pSrc;	// I420 based and after color space converted
+  int32_t		iDid;	// dependency id
 } SSpatialPicIndex;
 
 typedef struct TagStrideTables {
-int32_t*		pStrideDecBlockOffset[MAX_DEPENDENCY_LAYER][2];	// [iDid][tid==0][24 x 4]: luma+chroma= 24 x 4
-int32_t*		pStrideEncBlockOffset[MAX_DEPENDENCY_LAYER];		// [iDid][24 x 4]: luma+chroma= 24 x 4
-int16_t*		pMbIndexX[MAX_DEPENDENCY_LAYER];					// [iDid][iMbX]: map for iMbX in each spatial layer coding
-int16_t*		pMbIndexY[MAX_DEPENDENCY_LAYER];					// [iDid][iMbY]: map for iMbY in each spatial layer coding
+  int32_t*		pStrideDecBlockOffset[MAX_DEPENDENCY_LAYER][2];	// [iDid][tid==0][24 x 4]: luma+chroma= 24 x 4
+  int32_t*		pStrideEncBlockOffset[MAX_DEPENDENCY_LAYER];		// [iDid][24 x 4]: luma+chroma= 24 x 4
+  int16_t*		pMbIndexX[MAX_DEPENDENCY_LAYER];					// [iDid][iMbX]: map for iMbX in each spatial layer coding
+  int16_t*		pMbIndexY[MAX_DEPENDENCY_LAYER];					// [iDid][iMbY]: map for iMbY in each spatial layer coding
 } SStrideTables;
 
 typedef struct TagWelsEncCtx {
-SLogContext sLogCtx;
+  SLogContext sLogCtx;
 // Input
-SWelsSvcCodingParam*		pSvcParam;	// SVC parameter, WelsSVCParamConfig in svc_param_settings.h
-SWelsSliceBs*		 	pSliceBs;		// bitstream buffering for various slices, [uiSliceIdx]
+  SWelsSvcCodingParam*		pSvcParam;	// SVC parameter, WelsSVCParamConfig in svc_param_settings.h
+  SWelsSliceBs*		 	pSliceBs;		// bitstream buffering for various slices, [uiSliceIdx]
 
-int32_t*					pSadCostMb;
-/* MVD cost tables for Inter MB */
-int32_t              iMvRange;
-uint16_t*					pMvdCostTable; //[52];	// adaptive to spatial layers
-int32_t					  iMvdCostTableSize; //the size of above table
-int32_t					    iMvdCostTableStride; //the stride of above table
-SMVUnitXY*
-pMvUnitBlock4x4;	// (*pMvUnitBlock4x4[2])[MB_BLOCK4x4_NUM];	    // for store each 4x4 blocks' mv unit, the two swap after different d layer
-int8_t*
-pRefIndexBlock4x4;	// (*pRefIndexBlock4x4[2])[MB_BLOCK8x8_NUM];	    // for store each 4x4 blocks' pRef index, the two swap after different d layer
-int8_t*                      pNonZeroCountBlocks;	// (*pNonZeroCountBlocks)[MB_LUMA_CHROMA_BLOCK4x4_NUM];
-int8_t*
-pIntra4x4PredModeBlocks;	// (*pIntra4x4PredModeBlocks)[INTRA_4x4_MODE_NUM];  //last byte is not used; the first 4 byte is for the bottom 12,13,14,15 4x4 block intra mode, and 3 byte for (3,7,11)
+  int32_t*					pSadCostMb;
+  /* MVD cost tables for Inter MB */
+  int32_t              iMvRange;
+  uint16_t*					pMvdCostTable; //[52];	// adaptive to spatial layers
+  int32_t					  iMvdCostTableSize; //the size of above table
+  int32_t					    iMvdCostTableStride; //the stride of above table
+  SMVUnitXY*
+  pMvUnitBlock4x4;	// (*pMvUnitBlock4x4[2])[MB_BLOCK4x4_NUM];	    // for store each 4x4 blocks' mv unit, the two swap after different d layer
+  int8_t*
+  pRefIndexBlock4x4;	// (*pRefIndexBlock4x4[2])[MB_BLOCK8x8_NUM];	    // for store each 4x4 blocks' pRef index, the two swap after different d layer
+  int8_t*                      pNonZeroCountBlocks;	// (*pNonZeroCountBlocks)[MB_LUMA_CHROMA_BLOCK4x4_NUM];
+  int8_t*
+  pIntra4x4PredModeBlocks;	// (*pIntra4x4PredModeBlocks)[INTRA_4x4_MODE_NUM];  //last byte is not used; the first 4 byte is for the bottom 12,13,14,15 4x4 block intra mode, and 3 byte for (3,7,11)
 
-SMB**                          ppMbListD;	// [MAX_DEPENDENCY_LAYER];
-SStrideTables*				pStrideTab;	// stride tables for internal coding used
-SWelsFuncPtrList*			pFuncList;
+  SMB**                          ppMbListD;	// [MAX_DEPENDENCY_LAYER];
+  SStrideTables*				pStrideTab;	// stride tables for internal coding used
+  SWelsFuncPtrList*			pFuncList;
 
-SSliceThreading*				pSliceThreading;
+  SSliceThreading*				pSliceThreading;
 
 // SSlice context
-SSliceCtx*				pSliceCtxList;// slice context table for each dependency quality layer
+  SSliceCtx*				pSliceCtxList;// slice context table for each dependency quality layer
 // pointers
-SPicture*					pEncPic;			// pointer to current picture to be encoded
-SPicture*					pDecPic;			// pointer to current picture being reconstructed
-SPicture*					pRefPic;			// pointer to current reference picture
+  SPicture*					pEncPic;			// pointer to current picture to be encoded
+  SPicture*					pDecPic;			// pointer to current picture being reconstructed
+  SPicture*					pRefPic;			// pointer to current reference picture
 
-SDqLayer*
-pCurDqLayer;				// DQ layer context used to being encoded currently, for reference base layer to refer: pCurDqLayer->pRefLayer if applicable
-SDqLayer**					ppDqLayerList;			// overall DQ layers encoded for storage
+  SDqLayer*
+  pCurDqLayer;				// DQ layer context used to being encoded currently, for reference base layer to refer: pCurDqLayer->pRefLayer if applicable
+  SDqLayer**					ppDqLayerList;			// overall DQ layers encoded for storage
 
-SRefList**					ppRefPicListExt;		// reference picture list for SVC
-SPicture*					pRefList0[16];
-SLTRState*					pLtr;//[MAX_DEPENDENCY_LAYER];
-bool                          bCurFrameMarkedAsSceneLtr;
+  SRefList**					ppRefPicListExt;		// reference picture list for SVC
+  SPicture*					pRefList0[16];
+  SLTRState*					pLtr;//[MAX_DEPENDENCY_LAYER];
+  bool                          bCurFrameMarkedAsSceneLtr;
 // Derived
-int32_t						iCodingIndex;
-int32_t						iFrameIndex;			// count how many frames elapsed during coding context currently
-int32_t						iFrameNum;				// current frame number coding
-int32_t						iPOC;					// frame iPOC
-EWelsSliceType				eSliceType;			// currently coding slice type
-EWelsNalUnitType			eNalType;			// NAL type
-EWelsNalRefIdc				eNalPriority;		// NAL_Reference_Idc currently
-EWelsNalRefIdc				eLastNalPriority;	// NAL_Reference_Idc in last frame
-uint8_t						iNumRef0;
+  int32_t						iCodingIndex;
+  int32_t						iFrameIndex;			// count how many frames elapsed during coding context currently
+  int32_t						iFrameNum;				// current frame number coding
+  int32_t						iPOC;					// frame iPOC
+  EWelsSliceType				eSliceType;			// currently coding slice type
+  EWelsNalUnitType			eNalType;			// NAL type
+  EWelsNalRefIdc				eNalPriority;		// NAL_Reference_Idc currently
+  EWelsNalRefIdc				eLastNalPriority;	// NAL_Reference_Idc in last frame
+  uint8_t						iNumRef0;
 
-uint8_t						uiDependencyId;	// Idc of dependecy layer to be coded
-uint8_t						uiTemporalId;	// Idc of temporal layer to be coded
-bool						bNeedPrefixNalFlag;	// whether add prefix nal
-bool                      bEncCurFrmAsIdrFlag;
+  uint8_t						uiDependencyId;	// Idc of dependecy layer to be coded
+  uint8_t						uiTemporalId;	// Idc of temporal layer to be coded
+  bool						bNeedPrefixNalFlag;	// whether add prefix nal
+  bool                      bEncCurFrmAsIdrFlag;
 
 // Rate control routine
-SWelsSvcRc*					pWelsSvcRc;
-int32_t						iSkipFrameFlag; //_GOM_RC_
-int32_t						iGlobalQp;		// global qp
+  SWelsSvcRc*					pWelsSvcRc;
+  int32_t						iSkipFrameFlag; //_GOM_RC_
+  int32_t						iGlobalQp;		// global qp
 
 // VAA
-SVAAFrameInfo*		    	pVaa;		    // VAA information of reference
-CWelsPreProcess*				pVpp;
+  SVAAFrameInfo*		    	pVaa;		    // VAA information of reference
+  CWelsPreProcess*				pVpp;
 
-SWelsSPS*							pSpsArray;		// MAX_SPS_COUNT by standard compatible
-SWelsSPS*							pSps;
-SWelsPPS*							pPPSArray;		// MAX_PPS_COUNT by standard compatible
-SWelsPPS*							pPps;
-/* SVC only */
-SSubsetSps*					pSubsetArray;	// MAX_SPS_COUNT by standard compatible
-SSubsetSps*					pSubsetSps;
-int32_t						iSpsNum;	// number of pSps used
-int32_t						iPpsNum;	// number of pPps used
+  SWelsSPS*							pSpsArray;		// MAX_SPS_COUNT by standard compatible
+  SWelsSPS*							pSps;
+  SWelsPPS*							pPPSArray;		// MAX_PPS_COUNT by standard compatible
+  SWelsPPS*							pPps;
+  /* SVC only */
+  SSubsetSps*					pSubsetArray;	// MAX_SPS_COUNT by standard compatible
+  SSubsetSps*					pSubsetSps;
+  int32_t						iSpsNum;	// number of pSps used
+  int32_t						iPpsNum;	// number of pPps used
 
 // Output
-SWelsEncoderOutput*			pOut;			// for NAL raw pData (need allocating memory for sNalList internal)
-uint8_t*						pFrameBs;		// restoring bitstream pBuffer of all NALs in a frame
-int32_t						iFrameBsSize;	// count size of frame bs in bytes allocated
-int32_t						iPosBsBuffer;	// current writing position of frame bs pBuffer
+  SWelsEncoderOutput*			pOut;			// for NAL raw pData (need allocating memory for sNalList internal)
+  uint8_t*						pFrameBs;		// restoring bitstream pBuffer of all NALs in a frame
+  int32_t						iFrameBsSize;	// count size of frame bs in bytes allocated
+  int32_t						iPosBsBuffer;	// current writing position of frame bs pBuffer
 
-SSpatialPicIndex			sSpatialIndexMap[MAX_DEPENDENCY_LAYER];
+  SSpatialPicIndex			sSpatialIndexMap[MAX_DEPENDENCY_LAYER];
 
-bool						bLongTermRefFlag[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL + 1/*+LONG_TERM_REF_NUM*/];
+  bool						bLongTermRefFlag[MAX_DEPENDENCY_LAYER][MAX_TEMPORAL_LEVEL + 1/*+LONG_TERM_REF_NUM*/];
 
-int16_t						iMaxSliceCount;// maximal count number of slices for all layers observation
-int16_t						iActiveThreadsNum;	// number of threads active so far
+  int16_t						iMaxSliceCount;// maximal count number of slices for all layers observation
+  int16_t						iActiveThreadsNum;	// number of threads active so far
 
-/*
- * DQ layer idc map for svc encoding, might be a better scheme than that of design before,
- * can aware idc of referencing layer and that idc of successive layer to be coded
- */
-/* SVC only */
-SDqIdc*
-pDqIdcMap;	// overall DQ map of full scalability in specific frame (All full D/T/Q layers involved)												// pDqIdcMap[dq_index] for each SDqIdc pData
+  /*
+   * DQ layer idc map for svc encoding, might be a better scheme than that of design before,
+   * can aware idc of referencing layer and that idc of successive layer to be coded
+   */
+  /* SVC only */
+  SDqIdc*
+  pDqIdcMap;	// overall DQ map of full scalability in specific frame (All full D/T/Q layers involved)												// pDqIdcMap[dq_index] for each SDqIdc pData
 
-SParaSetOffset				sPSOVector;
-CMemoryAlign*				pMemAlign;
+  SParaSetOffset				sPSOVector;
+  CMemoryAlign*				pMemAlign;
 
 #if defined(STAT_OUTPUT)
 // overall stat pData, refer to SStatData in stat.h, in case avc to use stat[0][0]
-SStatData					sStatData [ MAX_DEPENDENCY_LAYER ] [ MAX_QUALITY_LEVEL ];
-SStatSliceInfo				sPerInfo;
+  SStatData					sStatData [ MAX_DEPENDENCY_LAYER ] [ MAX_QUALITY_LEVEL ];
+  SStatSliceInfo				sPerInfo;
 #endif//STAT_OUTPUT
 
-int32_t iEncoderError;
-WELS_MUTEX					mutexEncoderError;
-int32_t iDropNumber;
+  int32_t iEncoderError;
+  WELS_MUTEX					mutexEncoderError;
+  bool bDeliveryFlag;
 
 #ifdef ENABLE_FRAME_DUMP
-bool bDependencyRecFlag[MAX_DEPENDENCY_LAYER];
-bool bRecFlag;
+  bool bDependencyRecFlag[MAX_DEPENDENCY_LAYER];
+  bool bRecFlag;
 #endif
 } sWelsEncCtx/*, *PWelsEncCtx*/;
 }
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -709,7 +709,7 @@
       || (dIncPercent > pWelsSvcRc->iRcVaryPercentage)) {
     pEncCtx->iSkipFrameFlag = 1;
     pWelsSvcRc->iBufferFullnessSkip = pWelsSvcRc->iBufferFullnessSkip - kiOutputBits;
-    WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO,"skip one frame");
+    WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_INFO, "skip one frame");
   }
 
   if (pWelsSvcRc->iBufferFullnessSkip < 0)
@@ -1005,8 +1005,10 @@
     iMinQp = MIN_SCREEN_QP + 1;
   else
     iMinQp = MIN_SCREEN_QP;
-
-  pEncCtx->iGlobalQp += pEncCtx->iDropNumber;
+  if (pEncCtx->bDeliveryFlag)
+    pEncCtx->iGlobalQp -= 1;
+  else
+    pEncCtx->iGlobalQp += 2;
   pEncCtx->iGlobalQp = WELS_CLIP3 (pEncCtx->iGlobalQp, iMinQp, MAX_SCREEN_QP);
 }
 void  WelsRcInitModule (void* pCtx, RC_MODES iRcMode) {
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -901,7 +901,7 @@
   break;
   case ENCODER_OPTION_DELIVERY_STATUS: {
     SDeliveryStatus* pValue = (static_cast<SDeliveryStatus*> (pOption));
-    m_pEncContext->iDropNumber = pValue->iDropNum;
+    m_pEncContext->bDeliveryFlag = pValue->bDeliveryFlag;
   }
   break;
   case ENCODER_OPTION_COMPLEXITY: {