shithub: openh264

Download patch

ref: 7150d4feb13df0c0ec77bffb3827ebcac409d1f2
parent: fc97e3a60206736a0a9baf7b106430ecdabac02d
parent: 92237fa32901fe9eb92fea22c58fd68f2aff420b
author: sijchen <sijchen@cisco.com>
date: Mon Jun 1 06:40:25 EDT 2015

Merge pull request #1968 from sijchen/mup

[Encoder] Multiple updates on logging and UT

--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -537,7 +537,7 @@
   unsigned char*  pData[4];        ///< plane pData
   int       iPicWidth;             ///< luma picture width in x coordinate
   int       iPicHeight;            ///< luma picture height in y coordinate
-  long long uiTimeStamp;
+  long long uiTimeStamp;           ///< timestamp of the source picture, unit: millisecond
 } SSourcePicture;
 /**
 * @brief Structure for bit rate info
--- a/codec/api/svc/codec_ver.h
+++ b/codec/api/svc/codec_ver.h
@@ -4,12 +4,12 @@
 
 #include "codec_app_def.h"
 
-static const OpenH264Version g_stCodecVersion  = {1, 4, 0, 0};
-static const char* const g_strCodecVer  = "OpenH264 version:1.4.0.0";
+static const OpenH264Version g_stCodecVersion  = {1,4,1,0};
+static const char* const g_strCodecVer  = "OpenH264 version:1.4.1.0";
 
 #define OPENH264_MAJOR (1)
 #define OPENH264_MINOR (4)
-#define OPENH264_REVISION (0)
+#define OPENH264_REVISION (1)
 #define OPENH264_RESERVED (0)
 
 #endif  // CODEC_VER_H
--- a/codec/console/enc/src/welsenc.cpp
+++ b/codec/console/enc/src/welsenc.cpp
@@ -626,7 +626,7 @@
 int FillSpecificParameters (SEncParamExt& sParam) {
   /* Test for temporal, spatial, SNR scalability */
   sParam.iUsageType = CAMERA_VIDEO_REAL_TIME;
-  sParam.fMaxFrameRate	= 30.0f;		// input frame rate
+  sParam.fMaxFrameRate	= 60.0f;		// input frame rate
   sParam.iPicWidth		= 1280;			// width of picture in samples
   sParam.iPicHeight	= 720;			// height of picture in samples
   sParam.iTargetBitrate = 2500000;		// target bitrate desired
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -200,14 +200,13 @@
 
   }
   if (pCfg->iSpatialLayerNum > 1) {
-    int32_t iFinalWidth = pCfg->sSpatialLayers[pCfg->iSpatialLayerNum - 1].iVideoWidth;
-    int32_t iFinalHeight = pCfg->sSpatialLayers[pCfg->iSpatialLayerNum - 1].iVideoHeight;
-    for (i = 0; i < (pCfg->iSpatialLayerNum - 1); i++) {
-      SSpatialLayerConfig* fDlp = &pCfg->sSpatialLayers[i];
-      if ((fDlp->iVideoWidth > iFinalWidth) || (fDlp->iVideoHeight > iFinalHeight)) {
+    for (i = pCfg->iSpatialLayerNum - 1; i > 0; i--) {
+      SSpatialLayerConfig* fDlpUp = &pCfg->sSpatialLayers[i];
+      SSpatialLayerConfig* fDlp = &pCfg->sSpatialLayers[i-1];
+      if ((fDlp->iVideoWidth > fDlpUp->iVideoWidth) || (fDlp->iVideoHeight > fDlpUp->iVideoHeight)) {
         WelsLog (pLogCtx, WELS_LOG_ERROR,
-                 "ParamValidation,Invalid resolution layer(%d) resolution(%d x %d) should be less than the highest spatial layer resolution(%d x %d) ",
-                 i, fDlp->iVideoWidth, fDlp->iVideoHeight, iFinalWidth, iFinalHeight);
+                 "ParamValidation,Invalid resolution layer(%d) resolution(%d x %d) should be less than the upper spatial layer resolution(%d x %d) ",
+                 i, fDlp->iVideoWidth, fDlp->iVideoHeight, fDlpUp->iVideoWidth, fDlpUp->iVideoHeight);
         return ENC_RETURN_UNSUPPORTED_PARA;
       }
     }
@@ -2438,7 +2437,7 @@
   iRet	=	pCodingParam->DetermineTemporalSettings();
   if (iRet != ENC_RETURN_SUCCESS) {
     WelsLog (pLogCtx, WELS_LOG_ERROR,
-             "WelsInitEncoderExt(), DetermineTemporalSettings failed return %d (check in/out frame rate and temporal layer setting!)",
+             "WelsInitEncoderExt(), DetermineTemporalSettings failed return %d (check in/out frame rate and temporal layer setting! -- in/out = 2^x, x <= temppral_layer_num)",
              iRet);
     return iRet;
   }
@@ -3708,7 +3707,7 @@
   if (iSpatialNum < 1) {	// skip due to temporal layer settings (different frame rate)
     ++ pCtx->iCodingIndex;
     pFbi->eFrameType = videoFrameTypeSkip;
-    WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame, continual skipped %d frames",
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame due to preprocessing return (temporal layer settings or else), continual skipped %d frames",
              pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
     return ENC_RETURN_SUCCESS;
   }
@@ -3718,7 +3717,7 @@
     if (pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip)
       pCtx->pFuncList->pfRc.pfWelsUpdateBufferWhenSkip (pCtx, iSpatialNum);
     pFbi->eFrameType = eFrameType;
-    WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame, continual skipped %d frames",
+    WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame due to target_br, continual skipped %d frames",
              pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
     return ENC_RETURN_SUCCESS;
   }
@@ -3729,7 +3728,7 @@
                  (uint32_t)pSrcPic->uiTimeStamp);
     if (bSkip) {
       pFbi->eFrameType = videoFrameTypeSkip;
-      WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame, continual skipped %d frames",
+      WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "[Rc] Frame timestamp = %lld, skip one frame due to max_br, continual skipped %d frames",
                pSrcPic->uiTimeStamp, pCtx->iContinualSkipFrames);
       return ENC_RETURN_SUCCESS;
     }
--- a/codec/encoder/core/src/ratectl.cpp
+++ b/codec/encoder/core/src/ratectl.cpp
@@ -900,8 +900,8 @@
     pWelsSvcRc->iPredFrameBit = pWelsSvcRc->iFrameDqBits;
 
   WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
-           "[Rc] Frame timestamp = %lld, Frame type =%d, encoding_qp = %d, average qp = %3d, max qp = %3d, min qp = %3d, index = %8d, "
-           "iTid = %1d, used = %8d, bitsperframe = %8d, target = %8d, remaingbits = %8d, skipbuffersize = %8d",
+           "[Rc] Frame timestamp = %lld, Frame type = %d, encoding_qp = %d, average qp = %d, max qp = %d, min qp = %d, index = %d, "
+           "iTid = %d, used = %d, bitsperframe = %d, target = %d, remaingbits = %d, skipbuffersize = %d",
            uiTimeStamp, pEncCtx->eSliceType, pEncCtx->iGlobalQp, pWelsSvcRc->iAverageFrameQp, pWelsSvcRc->iMaxFrameQp,
            pWelsSvcRc->iMinFrameQp,
            pEncCtx->iFrameIndex, pEncCtx->uiTemporalId, pWelsSvcRc->iFrameDqBits, pWelsSvcRc->iBitsPerFrame,
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -559,7 +559,7 @@
   pStatistics->uiSkippedFrameCount += (kbCurrentFrameSkipped ? 1 : 0);
   int32_t iProcessedFrameCount = pStatistics->uiInputFrameCount - pStatistics->uiSkippedFrameCount;
   if (!kbCurrentFrameSkipped && iProcessedFrameCount != 0) {
-    pStatistics->fAverageFrameSpeedInMs += (kiCurrentFrameMs - pStatistics->fAverageFrameSpeedInMs)/iProcessedFrameCount;
+    pStatistics->fAverageFrameSpeedInMs += (kiCurrentFrameMs - pStatistics->fAverageFrameSpeedInMs) / iProcessedFrameCount;
   }
 
   // rate control related
@@ -586,7 +586,7 @@
 
   const int32_t kiDeltaFrames = static_cast<int32_t> (pStatistics->uiInputFrameCount -
                                 m_pEncContext->iLastStatisticsFrameCount);
-  if (kiDeltaFrames > m_pEncContext->pSvcParam->fMaxFrameRate) {
+  if (kiDeltaFrames > (m_pEncContext->pSvcParam->fMaxFrameRate * 2)) {
     const int64_t kiTimeDiff = kiCurrentFrameTs - pStatistics->iStatisticsTs;
     if (kiTimeDiff) {
       pStatistics->fLatestFrameRate = static_cast<float> ((pStatistics->uiInputFrameCount -
@@ -596,6 +596,15 @@
                                m_pEncContext->iLastStatisticsBytes) * 8 * 1000 / kiTimeDiff);
     }
 
+    if (m_pEncContext->pSvcParam->iRCMode == RC_QUALITY_MODE || m_pEncContext->pSvcParam->iRCMode == RC_BITRATE_MODE) {
+      if ((pStatistics->fLatestFrameRate > 0)
+          && WELS_ABS (m_pEncContext->pSvcParam->fMaxFrameRate - pStatistics->fLatestFrameRate) > 5) {
+        WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
+                 "Actual Input Framerate %f is different from framerate in setting %f, suggest to use other rate control modes",
+                 pStatistics->fLatestFrameRate, m_pEncContext->pSvcParam->fMaxFrameRate);
+      }
+    }
+
     // update variables
     pStatistics->iStatisticsTs = kiCurrentFrameTs;
     m_pEncContext->iLastStatisticsBytes = m_pEncContext->iTotalEncodedBytes;
@@ -607,6 +616,13 @@
   if (m_pEncContext->iStatisticsLogInterval > 0) {
     const int64_t kiTimeDiff = kiCurrentFrameTs - m_pEncContext->iLastStatisticsLogTs;
     if ((kiTimeDiff > m_pEncContext->iStatisticsLogInterval) || (0 == pStatistics->uiInputFrameCount % 300)) {
+
+      if (WELS_ABS (pStatistics->fAverageFrameRate - m_pEncContext->pSvcParam->fMaxFrameRate) > 30) {
+        WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_WARNING,
+                 "Actual Input Framerate %f is quite different from framerate in setting %f, please check setting or timestamp unit (ms)",
+                 pStatistics->fAverageFrameRate, m_pEncContext->pSvcParam->fMaxFrameRate);
+      }
+
       WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
                "EncoderStatistics: %dx%d, SpeedInMs: %f, fAverageFrameRate=%f, "
                "LastFrameRate=%f, LatestBitRate=%d, LastFrameQP=%d, uiInputFrameCount=%d, uiSkippedFrameCount=%d, "
@@ -918,29 +934,29 @@
   }
   break;
   case ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION: {
-    int32_t iValue = * (static_cast<int32_t*>(pOption));
+    int32_t iValue = * (static_cast<int32_t*> (pOption));
     EParameterSetStrategy eNewStrategy = CONSTANT_ID;
     switch (iValue) {
-      case 0:
-        eNewStrategy = CONSTANT_ID;
-        break;
-      case 0x01:
-        eNewStrategy = INCREASING_ID;
-        break;
-      case 0x02:
-        eNewStrategy = SPS_LISTING;
-        break;
-      case 0x03:
-        eNewStrategy = SPS_LISTING_AND_PPS_INCREASING;
-        break;
-      case 0x06:
-        eNewStrategy = SPS_PPS_LISTING;
-        break;
-      default:
-        WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR,
-                 " CWelsH264SVCEncoder::SetOption eSpsPpsIdStrategy(%d) not in valid range, unchanged! existing=%d",
-                 iValue, m_pEncContext->pSvcParam->eSpsPpsIdStrategy);
-        break;
+    case 0:
+      eNewStrategy = CONSTANT_ID;
+      break;
+    case 0x01:
+      eNewStrategy = INCREASING_ID;
+      break;
+    case 0x02:
+      eNewStrategy = SPS_LISTING;
+      break;
+    case 0x03:
+      eNewStrategy = SPS_LISTING_AND_PPS_INCREASING;
+      break;
+    case 0x06:
+      eNewStrategy = SPS_PPS_LISTING;
+      break;
+    default:
+      WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR,
+               " CWelsH264SVCEncoder::SetOption eSpsPpsIdStrategy(%d) not in valid range, unchanged! existing=%d",
+               iValue, m_pEncContext->pSvcParam->eSpsPpsIdStrategy);
+      break;
     }
 
     if (((eNewStrategy & SPS_LISTING) || (m_pEncContext->pSvcParam->eSpsPpsIdStrategy & SPS_LISTING))
--- a/openh264.rc
+++ b/openh264.rc
@@ -24,8 +24,8 @@
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,4,0,0
- PRODUCTVERSION 1,4,0,0
+ FILEVERSION 1,4,1,0
+ PRODUCTVERSION 1,4,1,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -43,12 +43,12 @@
             VALUE "Comments", "Cisco OpenH264 codec"
             VALUE "CompanyName", "Cisco Systems Inc."
             VALUE "FileDescription", "Cisco OpenH264 codec"
-            VALUE "FileVersion", "1.4.0.0"
+            VALUE "FileVersion", "1.4.1.0"
             VALUE "InternalName", "openh264.dll"
             VALUE "LegalCopyright", "� 2011-2015 Cisco and/or its affiliates. All rights reserved."
             VALUE "OriginalFilename", "openh264.dll"
             VALUE "ProductName", "Cisco OpenH264 codec"
-            VALUE "ProductVersion", "1.4.0.0"
+            VALUE "ProductVersion", "1.4.1.0"
         END
     END
     BLOCK "VarFileInfo"
--- a/test/encoder/EncUT_EncoderExt.cpp
+++ b/test/encoder/EncUT_EncoderExt.cpp
@@ -927,3 +927,112 @@
   // finish
   pPtrEnc->Uninitialize();
 }
+
+TEST_F (EncoderInterfaceTest, DiffResolutionCheck) {
+  SEncParamExt sEncParamExt;
+  int iResult = pPtrEnc->GetDefaultParams (&sEncParamExt);
+  EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
+
+  //actual encode param: iUsageType = 0, spatial_layer_num = 1, temporal_layer_num = 3, frame_rate = 28.248587, target_bitrate = 573000, denoise =0, background_detection = 1, adaptive_quant = 1, enable_crop_pic = 1, scenechange_detection = 0, enable_long_term_reference = 0, ltr_mark_period = 30, ltr_ref_num = 0, enable_multiple_slice = 1, padding = 0, rc_mode = 1, enable_frame_skip = 1, max_bitrate = 573000, max_nalu_size = 0s
+  //actual encode param: spatial 0: width=360, height=640, frame_rate=28.248587, spatial_bitrate=573000, max_layer_bitrate =895839855, max_nalu_size=0, slice_mode=1,this=0x7c62ee48
+  sEncParamExt.iUsageType = CAMERA_VIDEO_REAL_TIME;
+  sEncParamExt.iPicWidth = 360;
+  sEncParamExt.iPicHeight = 640;
+  sEncParamExt.iTargetBitrate = 1000000;
+  sEncParamExt.iRCMode = RC_BITRATE_MODE;
+  sEncParamExt.fMaxFrameRate = 24;
+
+  sEncParamExt.iTemporalLayerNum = 3;
+  sEncParamExt.iSpatialLayerNum = 3;
+  sEncParamExt.bEnableLongTermReference = 0;
+  sEncParamExt.bEnableSceneChangeDetect = 0;
+  sEncParamExt.bEnableFrameSkip = 1;
+  sEncParamExt.uiMaxNalSize = 0;
+
+  sEncParamExt.sSpatialLayers[0].uiLevelIdc = LEVEL_UNKNOWN;
+  sEncParamExt.sSpatialLayers[0].iVideoWidth = 90;
+  sEncParamExt.sSpatialLayers[0].iVideoHeight = 160;
+  sEncParamExt.sSpatialLayers[0].fFrameRate = 6;
+  sEncParamExt.sSpatialLayers[0].iSpatialBitrate = 80000;
+  sEncParamExt.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
+
+  sEncParamExt.sSpatialLayers[1].uiLevelIdc = LEVEL_UNKNOWN;
+  sEncParamExt.sSpatialLayers[1].iVideoWidth = 180;
+  sEncParamExt.sSpatialLayers[1].iVideoHeight = 320;
+  sEncParamExt.sSpatialLayers[1].fFrameRate = 12;
+  sEncParamExt.sSpatialLayers[1].iSpatialBitrate = 200000;
+  sEncParamExt.sSpatialLayers[1].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
+
+  sEncParamExt.sSpatialLayers[2].uiLevelIdc = LEVEL_UNKNOWN;
+  sEncParamExt.sSpatialLayers[2].iVideoWidth = 360;
+  sEncParamExt.sSpatialLayers[2].iVideoHeight = 640;
+  sEncParamExt.sSpatialLayers[2].fFrameRate = 24;
+  sEncParamExt.sSpatialLayers[2].iSpatialBitrate = 600000;
+  sEncParamExt.sSpatialLayers[2].sSliceCfg.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
+
+  pParamExt->iPicWidth = sEncParamExt.iPicWidth;
+  pParamExt->iPicHeight = sEncParamExt.iPicWidth;
+
+  iResult = pPtrEnc->InitializeExt (&sEncParamExt);
+  EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess)) << "iUsageType = " << sEncParamExt.iUsageType <<
+      ", iPicWidth = " << sEncParamExt.iPicWidth << ", iPicHeight = " << sEncParamExt.iPicHeight << ", iTargetBitrate = " <<
+      sEncParamExt.iTargetBitrate << ", fMaxFrameRate = " << sEncParamExt.fMaxFrameRate;
+
+  PrepareOneSrcFrame();
+  iResult = pPtrEnc->EncodeFrame (pSrcPic, &sFbi);
+  EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
+  pSrcPic->uiTimeStamp += 30;
+
+  //correct setting
+  sEncParamExt.iSpatialLayerNum = 2;
+  sEncParamExt.sSpatialLayers[1].uiLevelIdc = LEVEL_UNKNOWN;
+  sEncParamExt.sSpatialLayers[1].iVideoWidth = 360;
+  sEncParamExt.sSpatialLayers[1].iVideoHeight = 640;
+  sEncParamExt.sSpatialLayers[1].fFrameRate = 24;
+  sEncParamExt.sSpatialLayers[1].iSpatialBitrate = 600000;
+  iResult = pPtrEnc->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sEncParamExt);
+  EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
+
+  PrepareOneSrcFrame();
+  iResult = pPtrEnc->EncodeFrame (pSrcPic, &sFbi);
+  EXPECT_EQ (iResult, static_cast<int> (cmResultSuccess));
+  pSrcPic->uiTimeStamp += 30;
+
+  //incorrect setting
+  int uiTraceLevel = WELS_LOG_QUIET;
+  pPtrEnc->SetOption (ENCODER_OPTION_TRACE_LEVEL, &uiTraceLevel);
+
+  sEncParamExt.sSpatialLayers[1].iVideoWidth = 90;
+  sEncParamExt.sSpatialLayers[1].iVideoHeight = 160;
+  sEncParamExt.sSpatialLayers[1].fFrameRate = 6;
+  sEncParamExt.sSpatialLayers[1].iSpatialBitrate = 80000;
+
+  sEncParamExt.sSpatialLayers[0].iVideoWidth = 360;
+  sEncParamExt.sSpatialLayers[0].iVideoHeight = 640;
+  sEncParamExt.sSpatialLayers[0].fFrameRate = 24;
+  sEncParamExt.sSpatialLayers[0].iSpatialBitrate = 600000;
+  iResult = pPtrEnc->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sEncParamExt);
+  EXPECT_EQ (iResult, static_cast<int> (cmInitParaError));
+
+  //incorrect setting
+  sEncParamExt.iSpatialLayerNum = 3;
+  sEncParamExt.sSpatialLayers[1].iVideoWidth = 90;
+  sEncParamExt.sSpatialLayers[1].iVideoHeight = 160;
+  sEncParamExt.sSpatialLayers[1].fFrameRate = 6;
+  sEncParamExt.sSpatialLayers[1].iSpatialBitrate = 80000;
+
+  sEncParamExt.sSpatialLayers[0].iVideoWidth = 180;
+  sEncParamExt.sSpatialLayers[0].iVideoHeight = 320;
+  sEncParamExt.sSpatialLayers[0].fFrameRate = 12;
+  sEncParamExt.sSpatialLayers[0].iSpatialBitrate = 200000;
+
+  sEncParamExt.sSpatialLayers[2].iVideoWidth = 360;
+  sEncParamExt.sSpatialLayers[2].iVideoHeight = 640;
+  sEncParamExt.sSpatialLayers[2].fFrameRate = 24;
+  sEncParamExt.sSpatialLayers[2].iSpatialBitrate = 600000;
+  iResult = pPtrEnc->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sEncParamExt);
+  EXPECT_EQ (iResult, static_cast<int> (cmInitParaError));
+
+  // finish
+  pPtrEnc->Uninitialize();
+}