shithub: openh264

Download patch

ref: 11c159b6a29b21a73b3ce218286fef70893be5c5
parent: 8b7af7cbefc1f1de89eba3d9e7c366709a172f9c
author: Sijia Chen <sijchen@cisco.com>
date: Tue May 26 11:21:45 EDT 2015

add parameter checking on resolution and related UT

--- 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;
       }
     }
--- a/test/encoder/EncUT_EncoderExt.cpp
+++ b/test/encoder/EncUT_EncoderExt.cpp
@@ -927,3 +927,99 @@
   // 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;
+
+  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;
+
+  //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));
+
+  //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();
+}