shithub: openh264

Download patch

ref: 9816e3302d06892e6cc4aba04d151b99846b8b19
parent: 597b4eef73c3032175fded97504a8db6ccd33b6f
author: sijchen <sijchen@cisco.com>
date: Wed Feb 17 10:24:40 EST 2016

fix timestamp = 0 issue when rc mode is BITRATE mode

--- a/codec/encoder/core/inc/extern.h
+++ b/codec/encoder/core/inc/extern.h
@@ -93,7 +93,7 @@
  * \param   kpSrcPic    Source picture
  * \return  EFrameType (videoFrameTypeIDR/videoFrameTypeI/videoFrameTypeP)
  */
-int32_t WelsEncoderEncodeExt (sWelsEncCtx*, SFrameBSInfo* pFbi, const SSourcePicture* kpSrcPic,int64_t uiTimeStamp);
+int32_t WelsEncoderEncodeExt (sWelsEncCtx*, SFrameBSInfo* pFbi, const SSourcePicture* kpSrcPic);
 
 int32_t WelsEncoderEncodeParameterSets (sWelsEncCtx* pCtx, void* pDst);
 
--- a/codec/encoder/core/inc/rc.h
+++ b/codec/encoder/core/inc/rc.h
@@ -288,5 +288,7 @@
 void WelsRcInitFuncPointers (sWelsEncCtx* pEncCtx, RC_MODES iRcMode);
 void WelsRcFreeMemory (sWelsEncCtx* pCtx);
 
+long long GetTimestampForRc(const long long uiTimeStamp, const long long uiLastTimeStamp, const float fFrameRate);
+
 }
 #endif //RC_H
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -3716,7 +3716,7 @@
  * \pParam  pSrcPic         Source Picture
  * \return  EFrameType (videoFrameTypeIDR/videoFrameTypeI/videoFrameTypeP)
  */
-int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSourcePicture* pSrcPic,int64_t uiTimeStamp ) {
+int32_t WelsEncoderEncodeExt (sWelsEncCtx* pCtx, SFrameBSInfo* pFbi, const SSourcePicture* pSrcPic ) {
   if (pCtx == NULL) {
     return ENC_RETURN_MEMALLOCERR;
   }
@@ -3756,7 +3756,7 @@
   pCtx->iEncoderError = ENC_RETURN_SUCCESS;
   pCtx->bCurFrameMarkedAsSceneLtr = false;
   pFbi->iLayerNum = 0; // for initialization
-  pFbi->uiTimeStamp = uiTimeStamp;
+  pFbi->uiTimeStamp = GetTimestampForRc(pSrcPic->uiTimeStamp, pCtx->uiLastTimestamp, pCtx->pSvcParam->sSpatialLayers->fFrameRate);
   for (int32_t iNalIdx = 0; iNalIdx < MAX_LAYER_NUM_OF_FRAME; iNalIdx++) {
     pFbi->sLayerInfo[iNalIdx].eFrameType = videoFrameTypeSkip;
   }
@@ -3763,7 +3763,7 @@
   // perform csc/denoise/downsample/padding, generate spatial layers
   iSpatialNum = pCtx->pVpp->BuildSpatialPicList (pCtx, pSrcPic);
   if (pCtx->pFuncList->pfRc.pfWelsUpdateMaxBrWindowStatus) {
-    pCtx->pFuncList->pfRc.pfWelsUpdateMaxBrWindowStatus (pCtx, iSpatialNum,uiTimeStamp);
+    pCtx->pFuncList->pfRc.pfWelsUpdateMaxBrWindowStatus (pCtx, iSpatialNum, pFbi->uiTimeStamp);
   }
 
   if (iSpatialNum < 1) {
@@ -3809,7 +3809,7 @@
       pLayerBsInfo->eFrameType = eFrameType;
       WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
                "[Rc] Frame timestamp = %lld, skip one frame due to target_br, continual skipped %d frames",
-               uiTimeStamp, pCtx->iContinualSkipFrames);
+               pFbi->uiTimeStamp, pCtx->iContinualSkipFrames);
       ++ iSpatialIdx;
       if (pSvcParam->bSimulcastAVC) {
         if (pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip)
@@ -3830,13 +3830,13 @@
     //loop each layer to check if have skip frame when RC and frame skip enable
     if (pCtx->pFuncList->pfRc.pfWelsCheckSkipBasedMaxbr) {
       bool bSkip = pCtx->pFuncList->pfRc.pfWelsCheckSkipBasedMaxbr (pCtx, iSpatialNum, eFrameType,
-                   (uint32_t)uiTimeStamp);
+                   (uint32_t)pFbi->uiTimeStamp);
       if (bSkip) {
         eFrameType = videoFrameTypeSkip;
         pLayerBsInfo->eFrameType = videoFrameTypeSkip;
         WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
                  "[Rc] Frame timestamp = %lld, skip one frame due to max_br, continual skipped %d frames",
-                 uiTimeStamp, pCtx->iContinualSkipFrames);
+                 pFbi->uiTimeStamp, pCtx->iContinualSkipFrames);
         ++ iSpatialIdx;
         if (pSvcParam->bSimulcastAVC)
           continue;
@@ -3968,7 +3968,7 @@
                          eFrameType); //get reordering syntax used for writing slice header and transmit to encoder.
     PrefetchReferencePicture (pCtx, eFrameType); // update reference picture for current pDq layer
 
-    pCtx->pFuncList->pfRc.pfWelsRcPictureInit (pCtx, uiTimeStamp);
+    pCtx->pFuncList->pfRc.pfWelsRcPictureInit (pCtx, pFbi->uiTimeStamp);
     PreprocessSliceCoding (pCtx); // MUST be called after pfWelsRcPictureInit() and WelsInitCurrentLayer()
 
     //TODO Complexity Calculation here for screen content
@@ -4166,7 +4166,7 @@
     }
 
     if (NULL != pCtx->pFuncList->pfRc.pfWelsRcPostFrameSkipping
-        && pCtx->pFuncList->pfRc.pfWelsRcPostFrameSkipping (pCtx, iCurDid,uiTimeStamp)) {
+        && pCtx->pFuncList->pfRc.pfWelsRcPostFrameSkipping (pCtx, iCurDid, pFbi->uiTimeStamp)) {
 
       StackBackEncoderStatus (pCtx, eFrameType);
       ClearFrameBsInfo (pCtx, pFbi);
@@ -4182,7 +4182,7 @@
       WelsRcPostFrameSkippedUpdate (pCtx, iCurDid);
       WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO,
                "[Rc] Frame timestamp = %lld, skip one frame due to post skip, continual skipped %d frames",
-               uiTimeStamp, pCtx->iContinualSkipFrames);
+               pFbi->uiTimeStamp, pCtx->iContinualSkipFrames);
       pCtx->iEncoderError = ENC_RETURN_SUCCESS;
       return ENC_RETURN_SUCCESS;
     }
@@ -4200,7 +4200,7 @@
     }
 
     pCtx->pFuncList->pfRc.pfWelsRcPictureInfoUpdate (pCtx, iLayerSize);
-    RcTraceFrameBits (pCtx,uiTimeStamp);
+    RcTraceFrameBits (pCtx, pFbi->uiTimeStamp);
     pCtx->pDecPic->iFrameAverageQp = pCtx->pWelsSvcRc[iDidIdx].iAverageFrameQp;
 
     //update scc related
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -1541,4 +1541,11 @@
   }
 }
 
+long long GetTimestampForRc(const long long uiTimeStamp, const long long uiLastTimeStamp, const float fFrameRate) {
+  if ((uiLastTimeStamp == uiTimeStamp) || ((uiTimeStamp == 0) && (uiLastTimeStamp != -1))) {
+    return (uiLastTimeStamp + (int32_t) (1000.0 / fFrameRate));
+  }
+  return uiTimeStamp;
+}
+
 }//end of namespace
--- a/codec/encoder/plus/inc/welsEncoderExt.h
+++ b/codec/encoder/plus/inc/welsEncoderExt.h
@@ -100,7 +100,7 @@
   int InitializeInternal (SWelsSvcCodingParam* argv);
   void TraceParamInfo(SEncParamExt *pParam);
   void LogStatistics (const int64_t kiCurrentFrameTs,int32_t iMaxDid);
-  void UpdateStatistics(const int64_t kiCurrentFrameTs, SFrameBSInfo* pBsInfo, const int64_t kiCurrentFrameMs);
+  void UpdateStatistics(SFrameBSInfo* pBsInfo, const int64_t kiCurrentFrameMs);
 
   sWelsEncCtx*      m_pEncContext;
 
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -402,14 +402,7 @@
 
 int CWelsH264SVCEncoder ::EncodeFrameInternal (const SSourcePicture*  pSrcPic, SFrameBSInfo* pBsInfo) {
   const int64_t kiBeforeFrameUs = WelsTime();
-  int64_t uiTimeStamp = pSrcPic->uiTimeStamp;
-  if ((m_pEncContext->uiLastTimestamp == uiTimeStamp) || ((uiTimeStamp == 0) && (m_pEncContext->uiLastTimestamp != -1))) {
-    uiTimeStamp = m_pEncContext->uiLastTimestamp + (int32_t) (1000.0 /
-                  m_pEncContext->pSvcParam->sSpatialLayers->fFrameRate);
-  }
-  m_pEncContext->uiLastTimestamp = uiTimeStamp;
-
-  const int32_t kiEncoderReturn = WelsEncoderEncodeExt (m_pEncContext, pBsInfo, pSrcPic, uiTimeStamp);
+  const int32_t kiEncoderReturn = WelsEncoderEncodeExt (m_pEncContext, pBsInfo, pSrcPic);
   const int64_t kiCurrentFrameMs = (WelsTime() - kiBeforeFrameUs) / 1000;
 
   if ((kiEncoderReturn == ENC_RETURN_MEMALLOCERR) || (kiEncoderReturn == ENC_RETURN_MEMOVERFLOWFOUND)
@@ -422,7 +415,7 @@
     return cmUnknownReason;
   }
 
-  UpdateStatistics (uiTimeStamp, pBsInfo, kiCurrentFrameMs);
+  UpdateStatistics (pBsInfo, kiCurrentFrameMs);
 
   ///////////////////for test
 #ifdef OUTPUT_BIT_STREAM
@@ -573,8 +566,10 @@
   }
 }
 
-void CWelsH264SVCEncoder::UpdateStatistics (const int64_t kiCurrentFrameTs, SFrameBSInfo* pBsInfo,
+void CWelsH264SVCEncoder::UpdateStatistics (SFrameBSInfo* pBsInfo,
     const int64_t kiCurrentFrameMs) {
+
+  const int64_t kiCurrentFrameTs = m_pEncContext->uiLastTimestamp = pBsInfo->uiTimeStamp;
 
   int32_t iMaxDid = m_pEncContext->pSvcParam->iSpatialLayerNum - 1;
   SLayerBSInfo*  pLayerInfo = &pBsInfo->sLayerInfo[0];