shithub: openh264

Download patch

ref: 959a7b78b96c31e8caaf7fb107665a377d2792b8
parent: a0984298743f4886b19cc216e1d06bb640bb70e6
parent: 316f9f4dcb18fbc70f4665d5e104acb7240b2f4a
author: ruil2 <ruil2@cisco.com>
date: Wed Mar 21 05:25:07 EDT 2018

Merge pull request #2929 from sijchen/fix_option

[Encoder] fix wrong setting at encoder SetOption ENCODER_OPTION_IDR_INTERVAL

--- a/codec/encoder/core/src/encoder.cpp
+++ b/codec/encoder/core/src/encoder.cpp
@@ -387,6 +387,13 @@
     //pEncCtx->bEncCurFrmAsIdrFlag: 1. first frame should be IDR; 2. idr pause; 3. idr request
     iFrameType = (pEncCtx->pVaa->bIdrPeriodFlag || bSceneChangeFlag
                   || pParamInternal->bEncCurFrmAsIdrFlag) ? videoFrameTypeIDR : videoFrameTypeP;
+    if ( videoFrameTypeIDR == iFrameType ) {
+      WelsLog (& (pEncCtx->sLogCtx), WELS_LOG_DEBUG,
+               "encoding videoFrameTypeIDR due to ( bIdrPeriodFlag %d, bSceneChangeFlag %d, bEncCurFrmAsIdrFlag %d )",
+               pEncCtx->pVaa->bIdrPeriodFlag,
+               bSceneChangeFlag,
+               pParamInternal->bEncCurFrmAsIdrFlag);
+    }
 
     if (videoFrameTypeP == iFrameType && bSkipFrameFlag) {  // for frame skip, 1/5/2010
       iFrameType = videoFrameTypeSkip;
--- a/codec/encoder/core/src/wels_preprocess.cpp
+++ b/codec/encoder/core/src/wels_preprocess.cpp
@@ -366,9 +366,17 @@
 
   iSrcWidth   = pSvcParam->SUsedPicRect.iWidth;
   iSrcHeight  = pSvcParam->SUsedPicRect.iHeight;
-  if (pSvcParam->uiIntraPeriod)
+  if (pSvcParam->uiIntraPeriod) {
     pCtx->pVaa->bIdrPeriodFlag = (1 + pDlayerParamInternal->iFrameIndex >= (int32_t)pSvcParam->uiIntraPeriod) ? true :
                                  false;
+    if (pCtx->pVaa->bIdrPeriodFlag) {
+      WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG,
+           "pSvcParam->uiIntraPeriod=%d, pCtx->pVaa->bIdrPeriodFlag=%d",
+             pSvcParam->uiIntraPeriod,
+             pCtx->pVaa->bIdrPeriodFlag);
+    }
+  }
+
   pSrcPic = pScaledPicture->pScaledInputPicture ? pScaledPicture->pScaledInputPicture : GetCurrentOrigFrame (
               iDependencyId);
 
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -374,14 +374,18 @@
  */
 int CWelsH264SVCEncoder::EncodeFrame (const SSourcePicture* kpSrcPic, SFrameBSInfo* pBsInfo) {
   if (! (kpSrcPic && m_bInitialFlag && pBsInfo)) {
+    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::EncodeFrame(), cmInitParaError.");
     return cmInitParaError;
   }
-  if (kpSrcPic->iColorFormat != videoFormatI420)
+  if (kpSrcPic->iColorFormat != videoFormatI420) {
+    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::EncodeFrame(), wrong iColorFormat %d", kpSrcPic->iColorFormat);
     return cmInitParaError;
+  }
 
   const int32_t kiEncoderReturn = EncodeFrameInternal (kpSrcPic, pBsInfo);
 
   if (kiEncoderReturn != cmResultSuccess) {
+    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_ERROR, "CWelsH264SVCEncoder::EncodeFrame(), kiEncoderReturn %d", kiEncoderReturn);
     return kiEncoderReturn;
   }
 
@@ -539,7 +543,7 @@
     SSpatialLayerConfig* pSpatialCfg = &pParam->sSpatialLayers[i];
     WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
              "sSpatialLayers[%d]: .iVideoWidth= %d; .iVideoHeight= %d; .fFrameRate= %.6ff; .iSpatialBitrate= %d; .iMaxSpatialBitrate= %d; .sSliceArgument.uiSliceMode= %d; .sSliceArgument.iSliceNum= %d; .sSliceArgument.uiSliceSizeConstraint= %d;"
-             "uiProfileIdc = %d;uiLevelIdc = %d",
+             "uiProfileIdc = %d;uiLevelIdc = %d;iDLayerQp = %d",
              i, pSpatialCfg->iVideoWidth,
              pSpatialCfg->iVideoHeight,
              pSpatialCfg->fFrameRate,
@@ -549,7 +553,8 @@
              pSpatialCfg->sSliceArgument.uiSliceNum,
              pSpatialCfg->sSliceArgument.uiSliceSizeConstraint,
              pSpatialCfg->uiProfileIdc,
-             pSpatialCfg->uiLevelIdc
+             pSpatialCfg->uiLevelIdc,
+             pSpatialCfg->iDLayerQp
             );
     ++ i;
   }
@@ -715,19 +720,22 @@
 
     m_iCspInternal = iColorspace;
     WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
-             "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_DATAFORMAT, m_iCspInternal= 0x%x", m_iCspInternal);
+             "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_DATAFORMAT, m_iCspInternal = 0x%x", m_iCspInternal);
   }
   break;
   case ENCODER_OPTION_IDR_INTERVAL: { // IDR Interval
     int32_t iValue = * ((int32_t*)pOption);
     WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
-             "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_IDR_INTERVAL iValue= %d", iValue);
-    if (iValue < -1 || iValue == 0)
-      iValue = 1;
+             "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_IDR_INTERVAL iValue = %d", iValue);
+    if ( iValue <= -1 ) {
+      iValue = 0;
+    }
     if (iValue == (int32_t)m_pEncContext->pSvcParam->uiIntraPeriod) {
       return cmResultSuccess;
     }
     m_pEncContext->pSvcParam->uiIntraPeriod = (uint32_t)iValue;
+    WelsLog (&m_pWelsTrace->m_sLogCtx, WELS_LOG_INFO,
+             "CWelsH264SVCEncoder::SetOption():ENCODER_OPTION_IDR_INTERVAL uiIntraPeriod updated to %d", m_pEncContext->pSvcParam->uiIntraPeriod);
   }
   break;
   case ENCODER_OPTION_SVC_ENCODE_PARAM_BASE: { // SVC Encoding Parameter
--- a/test/api/encode_decode_api_test.cpp
+++ b/test/api/encode_decode_api_test.cpp
@@ -95,7 +95,7 @@
   memset (buf_.data() + lumaSize, rand() % 256, (frameSize - lumaSize));
   int rv = encoder_->EncodeFrame (&EncPic, &info);
   if (0 == iCheckTypeIndex)
-    ASSERT_TRUE (rv == cmResultSuccess);
+    ASSERT_TRUE (rv == cmResultSuccess) << rv;
   else if (1 == iCheckTypeIndex)
     ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnknownReason);
 }
--- a/test/api/encode_options_test.cpp
+++ b/test/api/encode_options_test.cpp
@@ -2332,3 +2332,48 @@
 
 }
 
+TEST_F (EncodeDecodeTestAPI, ENCODER_OPTION_IDR_INTERVAL) {
+  int iSpatialLayerNum = 1;
+  int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
+  int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
+  float fFrameRate = rand() + 0.5f;
+  int iSliceNum        = 1;
+  encoder_->GetDefaultParams (&param_);
+  prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
+  param_.iTemporalLayerNum = 1;
+
+  int iTraceLevel = WELS_LOG_QUIET;
+  int rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
+  EXPECT_TRUE (rv == cmResultSuccess);
+
+  rv = encoder_->InitializeExt (&param_);
+  ASSERT_TRUE (rv == cmResultSuccess);
+
+  InitialEncDec (param_.iPicWidth, param_.iPicHeight);
+  EncodeOneFrame (0);
+  EXPECT_TRUE (info.eFrameType == videoFrameTypeIDR);
+
+  int iLastIdrIdx = 0;
+  int iFrame = 1;
+  int iTtlAttempt = (rand() % 5) + 2;
+  for (int iAtt = 0; iAtt < iTtlAttempt; iAtt++) {
+    int kiTargetIntraPeriod = WelsClip3 ((rand() % ENCODE_FRAME_NUM) - 1, -1, ENCODE_FRAME_NUM);
+    rv = encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &kiTargetIntraPeriod);
+    EXPECT_TRUE (rv == cmResultSuccess);
+
+    int iEncFrameNum = kiTargetIntraPeriod * 3;
+    for (int i = 0; i < iEncFrameNum; i++) {
+      EncodeOneFrame (0);
+
+      if ((kiTargetIntraPeriod <= 0) || (((iFrame - iLastIdrIdx) % kiTargetIntraPeriod) == 0)) {
+        EXPECT_TRUE (info.eFrameType == videoFrameTypeIDR) << "kiTargetIntraPeriod " << kiTargetIntraPeriod <<
+            " info.eFrameType " << info.eFrameType << " Frame " << i;
+        iLastIdrIdx = iFrame;
+      } else {
+        EXPECT_FALSE (info.eFrameType == videoFrameTypeIDR);
+      }
+
+      iFrame ++;
+    }
+  }
+}