• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <gtest/gtest.h>
2 #include "codec_def.h"
3 #include "utils/BufferedData.h"
4 #include "utils/FileInputStream.h"
5 #include "BaseDecoderTest.h"
6 #include "BaseEncoderTest.h"
7 #include "wels_common_defs.h"
8 #include <string>
9 #include <vector>
10 #include "encode_decode_api_test.h"
11 using namespace WelsCommon;
12 
InitialEncDec(int iWidth,int iHeight)13 bool EncodeDecodeTestAPIBase::InitialEncDec (int iWidth, int iHeight) {
14   // for encoder
15   // I420: 1(Y) + 1/4(U) + 1/4(V)
16   int frameSize = iWidth * iHeight * 3 / 2;
17 
18   buf_.SetLength (frameSize);
19   if (buf_.Length() != (size_t)frameSize) { //include memory fail (-1) case
20     printf ("buf_.Length() failed! frameSize = %d\n", frameSize);
21     return false;
22   }
23 
24   memset (&EncPic, 0, sizeof (SSourcePicture));
25   EncPic.iPicWidth    = iWidth;
26   EncPic.iPicHeight   =  iHeight;
27   EncPic.iColorFormat = videoFormatI420;
28   EncPic.iStride[0]   = EncPic.iPicWidth;
29   EncPic.iStride[1]   = EncPic.iStride[2] = EncPic.iPicWidth >> 1;
30   EncPic.pData[0]     = buf_.data();
31   EncPic.pData[1]     = EncPic.pData[0] + iWidth * iHeight;
32   EncPic.pData[2]     = EncPic.pData[1] + (iWidth * iHeight >> 2);
33 
34   //for decoder
35   memset (&info, 0, sizeof (SFrameBSInfo));
36 
37   //set a fixed random value
38   iRandValue = rand() % 256;
39   memset (buf_.data(), iRandValue, frameSize);
40   return true;
41 }
42 
RandomParamExtCombination()43 void EncodeDecodeTestAPIBase::RandomParamExtCombination() {
44 
45   param_.iPicWidth  = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 2, MAX_WIDTH);
46   param_.iPicHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 2, MAX_HEIGHT);
47 
48   param_.fMaxFrameRate      = rand() % FRAME_RATE_RANGE + 0.5f;
49   param_.iUsageType         = static_cast<EUsageType> (rand() % 2);
50   param_.iTemporalLayerNum  = rand() % TEMPORAL_LAYER_NUM_RANGE;
51   param_.iSpatialLayerNum   = rand() % SPATIAL_LAYER_NUM_RANGE;
52 
53   param_.uiIntraPeriod      = rand() - 1;
54   param_.iNumRefFrame       = AUTO_REF_PIC_COUNT;
55   param_.iMultipleThreadIdc = rand();
56 
57   int iValue   = rand() % 7;
58   switch (iValue) {
59   case 0:
60     param_.eSpsPpsIdStrategy  = CONSTANT_ID;
61     break;
62   case 0x01:
63     param_.eSpsPpsIdStrategy  = INCREASING_ID;
64     break;
65   case 0x02:
66     param_.eSpsPpsIdStrategy  = SPS_LISTING;
67     break;
68   case 0x03:
69     param_.eSpsPpsIdStrategy  = SPS_LISTING_AND_PPS_INCREASING;
70     break;
71   case 0x06:
72     param_.eSpsPpsIdStrategy  = SPS_PPS_LISTING;
73     break;
74   default:
75     param_.eSpsPpsIdStrategy  = CONSTANT_ID;
76     break;
77   }
78   param_.bPrefixNalAddingCtrl      = (rand() % 2 == 0) ? false : true;
79   param_.bEnableSSEI               = (rand() % 2 == 0) ? false : true;
80   param_.iPaddingFlag              = rand() % 2;
81 
82   //LTR
83   param_.bEnableLongTermReference  = (rand() % 2 == 0) ? false : true;
84   param_.bIsLosslessLink           = (rand() % 2 == 0) ? false : true;
85   param_.iLTRRefNum                = rand();
86   param_.iLtrMarkPeriod            = rand();
87 
88   //loop filter
89   param_.iLoopFilterDisableIdc     = rand() % 7;
90   param_.iLoopFilterAlphaC0Offset  = rand();
91   param_.iLoopFilterBetaOffset     = rand();
92 
93   param_.bEnableDenoise             = (rand() % 2 == 0) ? false : true;
94   param_.bEnableBackgroundDetection = (rand() % 2 == 0) ? false : true;
95   param_.bEnableAdaptiveQuant       = (rand() % 2 == 0) ? false : true;
96   param_.bEnableFrameCroppingFlag   = (rand() % 2 == 0) ? false : true;
97   param_.bEnableSceneChangeDetect   = (rand() % 2 == 0) ? false : true;
98 
99   //for rc
100   param_.iRCMode            = static_cast<RC_MODES> (rand() % RC_MODE_RANGE - 1);
101   param_.iMaxBitrate        = rand() % BIT_RATE_RANGE;
102   param_.iTargetBitrate     = rand() % BIT_RATE_RANGE;
103   param_.iMaxQp             = rand() % QP_RANGE;
104   param_.iMinQp             = rand() % QP_RANGE;
105   param_.uiMaxNalSize       = rand();
106   param_.bEnableFrameSkip   = (rand() % 2 == 0) ? false : true;
107 
108   for (int iSpatialIdx = 0; iSpatialIdx < param_.iSpatialLayerNum; iSpatialIdx++) {
109     if (iSpatialIdx < MAX_SPATIAL_LAYER_NUM) {
110       SSpatialLayerConfig* pSpatialLayer = &param_.sSpatialLayers[iSpatialIdx];
111 
112       //to do: profile and level id
113       //pSpatialLayer->uiProfileIdc        = 0;
114       //pSpatialLayer->uiLevelIdc          = 0;
115       pSpatialLayer->iVideoWidth         = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 2, MAX_WIDTH);
116       pSpatialLayer->iVideoHeight        = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 2, MAX_HEIGHT);
117       pSpatialLayer->fFrameRate          = rand() % FRAME_RATE_RANGE + 0.5f;
118       pSpatialLayer->iMaxSpatialBitrate  = rand() % BIT_RATE_RANGE;
119       pSpatialLayer->iSpatialBitrate     = rand() % BIT_RATE_RANGE;
120 
121 
122       pSpatialLayer->sSliceArgument.uiSliceMode = static_cast<SliceModeEnum> (rand() % SLICE_MODE_NUM);
123       if (pSpatialLayer->sSliceArgument.uiSliceMode != SM_SIZELIMITED_SLICE) {
124         param_.uiMaxNalSize       = 0;
125       }
126       pSpatialLayer->sSliceArgument.uiSliceNum = rand();
127       pSpatialLayer->sSliceArgument.uiSliceSizeConstraint = rand();
128     }
129   }
130 }
131 
ValidateParamExtCombination()132 void EncodeDecodeTestAPIBase::ValidateParamExtCombination() {
133 
134   bool bDynSliceModeFlag   = false;
135   unsigned int uiGOPSize   = 0;
136   unsigned int uiSliceNum  = 0;
137   int iTotalBitRate        = 0;
138   int iMinQP               = 0;
139 
140   param_.iPicWidth          = WELS_CLIP3 (param_.iPicWidth,  2, MAX_WIDTH);
141   param_.iPicHeight         = WELS_CLIP3 (param_.iPicHeight, 2, MAX_HEIGHT);
142   param_.fMaxFrameRate      = WELS_CLIP3 (param_.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
143   param_.iTemporalLayerNum  = WELS_CLIP3 (param_.iTemporalLayerNum, 1, MAX_TEMPORAL_LAYER_NUM);
144 
145   if (CAMERA_VIDEO_REAL_TIME == param_.iUsageType)
146     param_.iSpatialLayerNum   = WELS_CLIP3 (param_.iSpatialLayerNum, 1, MAX_SPATIAL_LAYER_NUM);
147   else
148     param_.iSpatialLayerNum   = 1;
149 
150   //IntraPeriod
151   uiGOPSize = 1 << (param_.iTemporalLayerNum - 1);
152   param_.uiIntraPeriod -= param_.uiIntraPeriod % uiGOPSize;
153 
154   //RefNum
155   int32_t iRefUpperBound    = (param_.iUsageType == CAMERA_VIDEO_REAL_TIME) ?
156                               MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA : MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN;
157   param_.iNumRefFrame       = WELS_CLIP3 (param_.iNumRefFrame, MIN_REF_PIC_COUNT, iRefUpperBound);
158 
159   //to do: will add more validate logic for thread number
160   param_.iMultipleThreadIdc = 1;
161 
162   //LTR
163   //iLTRRefNum: not supported to set it arbitrary yet
164   if (true == param_.bEnableLongTermReference) {
165     param_.iLTRRefNum     = (SCREEN_CONTENT_REAL_TIME == param_.iUsageType) ? LONG_TERM_REF_NUM_SCREEN : LONG_TERM_REF_NUM;
166     param_.iLtrMarkPeriod = (0 == param_.iLtrMarkPeriod) ? 1 : param_.iLtrMarkPeriod;
167 
168   } else {
169     param_.iLTRRefNum = 0;
170   }
171 
172   //loop filter
173   param_.iLoopFilterDisableIdc    = param_.iLoopFilterDisableIdc    % LOOP_FILTER_IDC_NUM;
174   param_.iLoopFilterAlphaC0Offset = param_.iLoopFilterAlphaC0Offset % (2 * LOOF_FILTER_OFFSET_RANGE + 1) -
175                                     LOOF_FILTER_OFFSET_RANGE;
176   param_.iLoopFilterBetaOffset    = param_.iLoopFilterBetaOffset    % (2 * LOOF_FILTER_OFFSET_RANGE + 1) -
177                                     LOOF_FILTER_OFFSET_RANGE;
178 
179   for (int iSpatialIdx = 0; iSpatialIdx < param_.iSpatialLayerNum; iSpatialIdx++) {
180     SSpatialLayerConfig* pSpatialLayer = &param_.sSpatialLayers[iSpatialIdx];
181     pSpatialLayer->iVideoWidth  = param_.iPicWidth >> (param_.iSpatialLayerNum - 1 - iSpatialIdx);
182     pSpatialLayer->iVideoHeight = param_.iPicHeight >> (param_.iSpatialLayerNum - 1 - iSpatialIdx);
183     pSpatialLayer->fFrameRate   = param_.fMaxFrameRate;
184 
185     pSpatialLayer->iMaxSpatialBitrate  = WELS_CLIP3 (pSpatialLayer->iMaxSpatialBitrate, 1, BIT_RATE_RANGE);
186     pSpatialLayer->iSpatialBitrate     = WELS_CLIP3 (pSpatialLayer->iSpatialBitrate, 1, pSpatialLayer->iMaxSpatialBitrate);
187     iTotalBitRate += pSpatialLayer->iSpatialBitrate;
188 
189     uiSliceNum  = pSpatialLayer->sSliceArgument.uiSliceNum;
190     pSpatialLayer->sSliceArgument.uiSliceNum = WELS_CLIP3 (uiSliceNum, 1, MAX_SLICES_NUM);
191     pSpatialLayer->sSliceArgument.uiSliceSizeConstraint = 0;
192 
193 
194     //for SM_FIXEDSLCNUM_SLICE
195     // to do will add this when GOM bug fixed
196     if (SM_FIXEDSLCNUM_SLICE == pSpatialLayer->sSliceArgument.uiSliceMode) {
197       pSpatialLayer->sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
198     }
199 
200     //for slice mode = SM_SIZELIMITED_SLICE
201     if (SM_SIZELIMITED_SLICE == pSpatialLayer->sSliceArgument.uiSliceMode) {
202       bDynSliceModeFlag = true;
203     }
204 
205     //for slice mode = SM_RASTER_SLICE
206     if (SM_RASTER_SLICE == pSpatialLayer->sSliceArgument.uiSliceMode) {
207       if (0 != pSpatialLayer->sSliceArgument.uiSliceMbNum[0]) {
208         SliceParamValidationForMode2 (iSpatialIdx);
209       } else {
210         SliceParamValidationForMode3 (iSpatialIdx);
211       }
212     }
213   }
214 
215   //for RC
216   if ((RC_QUALITY_MODE == param_.iRCMode) || (RC_BITRATE_MODE == param_.iRCMode)) {
217     param_.bEnableFrameSkip = true;
218   }
219   if (param_.iTargetBitrate < iTotalBitRate) {
220     param_.iTargetBitrate = iTotalBitRate;
221   }
222   if (param_.iMaxBitrate < param_.iTargetBitrate) {
223     param_.iMaxBitrate = param_.iTargetBitrate;
224   }
225   param_.iMaxQp       = WELS_CLIP3 (param_.iMaxQp, MIN_QP, MAX_QP);
226   param_.iMinQp       = WELS_CLIP3 (param_.iMinQp, MIN_QP, MAX_QP);
227   iMinQP              = (param_.iMaxQp < param_.iMinQp) ? param_.iMaxQp : param_.iMinQp;
228   param_.iMaxQp       = (param_.iMaxQp > param_.iMinQp) ? param_.iMaxQp : param_.iMinQp;
229   param_.iMinQp       = iMinQP;
230   param_.uiMaxNalSize = 0;
231 
232   //for slice mode = SM_SIZELIMITED_SLICE
233   if (true == bDynSliceModeFlag) {
234     SliceParamValidationForMode4();
235   }
236 
237 }
238 
239 
SliceParamValidationForMode2(int iSpatialIdx)240 void EncodeDecodeTestAPIBase::SliceParamValidationForMode2 (int iSpatialIdx) {
241 
242   unsigned int uiMbWidth          = 0;
243   unsigned int uiMbHeight         = 0;
244   unsigned int uiMbNumInFrame     = 0;
245   unsigned int uiCountMb          = 0;
246   unsigned int uiSliceIdx         = 0;
247   unsigned int uiActualSliceCount = 0;
248 
249   uiMbWidth      = (param_.iPicWidth  + 15) >> 4;
250   uiMbHeight     = (param_.iPicHeight + 15) >> 4;
251   uiMbNumInFrame = uiMbWidth * uiMbHeight;
252 
253   uiSliceIdx = 0;
254   while (uiSliceIdx < MAX_SLICES_NUM) {
255     param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMbNum[uiSliceIdx] = rand() % uiMbNumInFrame;
256     uiCountMb           += param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMbNum[uiSliceIdx];
257     uiActualSliceCount   =  uiSliceIdx + 1;
258 
259     if (uiCountMb >= uiMbNumInFrame) {
260       break;
261     }
262 
263     ++ uiSliceIdx;
264   }
265 
266   if (uiCountMb >= uiMbNumInFrame) {
267     param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMbNum[uiActualSliceCount - 1] -=
268       (uiCountMb - uiMbNumInFrame);
269 
270   } else {
271     param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMbNum[uiActualSliceCount - 1 ] +=
272       (uiMbNumInFrame - uiCountMb);
273   }
274   param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceNum = uiActualSliceCount;
275 
276 }
SliceParamValidationForMode3(int iSpatialIdx)277 void EncodeDecodeTestAPIBase::SliceParamValidationForMode3 (int iSpatialIdx) {
278 
279   unsigned int uiMbHeight         = 0;
280 
281   uiMbHeight = (param_.iPicHeight + 15) >> 4;
282 
283   //change slice mode to SM_SINGLE_SLICE
284   if (uiMbHeight >  MAX_SLICES_NUM) {
285     param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
286   }
287 
288 }
289 
SliceParamValidationForMode4()290 void EncodeDecodeTestAPIBase::SliceParamValidationForMode4() {
291   //slice mode of all spatial layer should be set as SM_SIZELIMITED_SLICE
292   for (int iSpatialIdx = 0; iSpatialIdx < param_.iSpatialLayerNum; iSpatialIdx++) {
293     param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceSizeConstraint = 600;
294     param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMode = SM_SIZELIMITED_SLICE;
295   }
296   param_.uiMaxNalSize = 1500;
297 }
298 
TEST_F(EncodeDecodeTestAPI,SetOptionEncParamExt)299 TEST_F (EncodeDecodeTestAPI, SetOptionEncParamExt) {
300   int iSpatialLayerNum = 4;
301   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
302   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
303   float fFrameRate = rand() + 0.5f;
304   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
305   int iSliceNum        = 1;
306   encoder_->GetDefaultParams (&param_);
307   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
308 
309   int rv = encoder_->InitializeExt (&param_);
310   ASSERT_TRUE (rv == cmResultSuccess);
311 
312   int iTraceLevel = WELS_LOG_QUIET;
313   rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
314   ASSERT_TRUE (rv == cmResultSuccess);
315 
316   for (int i = 0; i < iEncFrameNum; i++) {
317     int iResult;
318     int len = 0;
319     unsigned char* pData[3] = { NULL };
320 
321     RandomParamExtCombination();
322     iResult = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &param_);
323     //ValidateParamExtCombination();
324     //ASSERT_TRUE (iResult == cmResultSuccess);
325     //to do
326     // currently, there are still some error cases even though under condition cmResultSuccess == iResult
327     // so need to enhance the validation check for any random value of each variable in ParamExt
328 
329     if (cmResultSuccess == iResult) {
330       ASSERT_TRUE (InitialEncDec (param_.iPicWidth, param_.iPicHeight));
331       EncodeOneFrame (0);
332       encToDecData (info, len);
333       pData[0] = pData[1] = pData[2] = 0;
334       memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
335 
336       iResult = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
337       ASSERT_TRUE (iResult == cmResultSuccess);
338       iResult = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
339       ASSERT_TRUE (iResult == cmResultSuccess);
340       EXPECT_EQ (dstBufInfo_.iBufferStatus, 1);
341     }
342   }
343 
344   iTraceLevel = WELS_LOG_ERROR;
345   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
346 }
347 
348 
TEST_F(EncodeDecodeTestAPI,SetOptionEncParamBase)349 TEST_F (EncodeDecodeTestAPI, SetOptionEncParamBase) {
350   int iSpatialLayerNum = 4;
351   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
352   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
353   float fFrameRate = rand() + 0.5f;
354   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
355   int iSliceNum        = 1;
356   encoder_->GetDefaultParams (&param_);
357   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
358 
359   int rv = encoder_->InitializeExt (&param_);
360   ASSERT_TRUE (rv == cmResultSuccess);
361 
362   int iTraceLevel = WELS_LOG_QUIET;
363   rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
364   ASSERT_TRUE (rv == cmResultSuccess);
365 
366   for (int i = 0; i < iEncFrameNum; i++) {
367     int iResult;
368     int len = 0;
369     unsigned char* pData[3] = { NULL };
370 
371     param_.iTargetBitrate     = rand() % BIT_RATE_RANGE;
372     iResult = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_BASE, &param_);
373 
374     if (cmResultSuccess == iResult) {
375       ASSERT_TRUE (InitialEncDec (param_.iPicWidth, param_.iPicHeight));
376       EncodeOneFrame (0);
377       encToDecData (info, len);
378       pData[0] = pData[1] = pData[2] = 0;
379       memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
380 
381       iResult = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
382       ASSERT_TRUE (iResult == cmResultSuccess);
383       iResult = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
384       ASSERT_TRUE (iResult == cmResultSuccess);
385       EXPECT_EQ (dstBufInfo_.iBufferStatus, 1);
386     }
387   }
388 
389   iTraceLevel = WELS_LOG_ERROR;
390   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
391 }
392 
393 struct EncodeDecodeParamBase {
394   int width;
395   int height;
396   float frameRate;
397   int iTarBitrate;
398 };
399 
400 //#define DEBUG_FILE_SAVE_INCREASING_ID
TEST_F(EncodeDecodeTestAPI,ParameterSetStrategy_INCREASING_ID)401 TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_INCREASING_ID) {
402 
403   int iWidth       = GetRandWidth();
404   int iHeight      = GetRandHeight();
405   float fFrameRate = rand() + 0.5f;
406   int iEncFrameNum = 0;
407   int iSpatialLayerNum = 1;
408   int iSliceNum        = 1;
409 
410   // prepare params
411   SEncParamExt   sParam1;
412   SEncParamExt   sParam2;
413   SEncParamExt   sParam3;
414   encoder_->GetDefaultParams (&sParam1);
415   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
416   sParam1.bSimulcastAVC = 1;
417   sParam1.eSpsPpsIdStrategy = INCREASING_ID;
418   //prepare param2
419   memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
420   while (GET_MB_WIDTH (sParam2.iPicWidth) == GET_MB_WIDTH (sParam1.iPicWidth)) {
421     sParam2.iPicWidth = GetRandWidth();
422   }
423   prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
424   sParam2.bSimulcastAVC = 1;
425   sParam2.eSpsPpsIdStrategy = INCREASING_ID;
426   //prepare param3
427   memcpy (&sParam3, &sParam1, sizeof (SEncParamExt));
428   while (GET_MB_WIDTH (sParam3.iPicHeight) == GET_MB_WIDTH (sParam1.iPicHeight)) {
429     sParam3.iPicHeight = GetRandHeight();
430   }
431   prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam3.iPicWidth, sParam3.iPicHeight, fFrameRate, &sParam3);
432   sParam3.bSimulcastAVC = 1;
433   sParam3.eSpsPpsIdStrategy = INCREASING_ID;
434 
435   //prepare output if needed
436   FILE* fEnc =  NULL;
437 #ifdef DEBUG_FILE_SAVE_INCREASING_ID
438   fEnc = fopen ("enc_INCREASING_ID.264", "wb");
439 #endif
440 
441   // Test part#1
442   // step#1: pParam1
443   //int TraceLevel = WELS_LOG_INFO;
444   //encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
445   int rv = encoder_->InitializeExt (&sParam1);
446   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
447                                       sParam1.iPicHeight;
448   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
449 
450   // new IDR
451   rv = encoder_->ForceIntraFrame (true);
452   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
453   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
454 
455   // step#2: pParam2
456   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
457   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam2.iPicWidth << "x" <<
458                                       sParam2.iPicHeight;
459   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
460 
461   // new IDR
462   rv = encoder_->ForceIntraFrame (true);
463   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
464   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
465 
466   // step#3: back to pParam1
467   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
468   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
469                                       sParam1.iPicHeight;
470   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
471 
472   // step#4: back to pParam2
473   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
474   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv << sParam2.iPicWidth << sParam2.iPicHeight;
475   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
476 
477 #ifdef DEBUG_FILE_SAVE_INCREASING_ID
478   fclose (fEnc);
479 #endif
480   rv = encoder_->Uninitialize();
481   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
482 
483   // Test part#2
484   // step#1: pParam1
485   rv = encoder_->InitializeExt (&sParam1);
486   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt Failed: rv = " << rv;
487   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
488   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
489   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam3);
490   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam3: rv = " << rv;
491 
492 #ifdef DEBUG_FILE_SAVE_INCREASING_ID
493   fEnc = fopen ("enc_INCREASING_ID2.264", "wb");
494 #endif
495   iEncFrameNum = 0;
496   ASSERT_TRUE (EncDecOneFrame (sParam3.iPicWidth, sParam3.iPicHeight, iEncFrameNum++, fEnc));
497 
498   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
499   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
500   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
501 
502   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
503   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
504   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
505 
506 #ifdef DEBUG_FILE_SAVE_INCREASING_ID
507   fclose (fEnc);
508 #endif
509   rv = encoder_->Uninitialize();
510   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
511 }
512 
513 //#define DEBUG_FILE_SAVE2
TEST_F(EncodeDecodeTestAPI,ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING1)514 TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING1) {
515 
516   int iWidth       = GetRandWidth();
517   int iHeight      = GetRandHeight();
518   float fFrameRate = rand() + 0.5f;
519   int iEncFrameNum = 0;
520   int iSpatialLayerNum = 1;
521   int iSliceNum        = 1;
522 
523   // prepare params
524   SEncParamExt   sParam1;
525   SEncParamExt   sParam2;
526   SEncParamExt   sParam3;
527   encoder_->GetDefaultParams (&sParam1);
528   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
529   sParam1.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
530   //prepare param2
531   memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
532   while (GET_MB_WIDTH (sParam2.iPicWidth) == GET_MB_WIDTH (sParam1.iPicWidth)) {
533     sParam2.iPicWidth = GetRandWidth();
534   }
535   prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
536   sParam2.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
537   //prepare param3
538   memcpy (&sParam3, &sParam1, sizeof (SEncParamExt));
539   while (GET_MB_WIDTH (sParam3.iPicHeight) == GET_MB_WIDTH (sParam1.iPicHeight)) {
540     sParam3.iPicHeight = GetRandHeight();
541   }
542   prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam3.iPicWidth, sParam3.iPicHeight, fFrameRate, &sParam3);
543   sParam3.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
544 
545   //prepare output if needed
546   FILE* fEnc =  NULL;
547 #ifdef DEBUG_FILE_SAVE2
548   fEnc = fopen ("enc_SPS_LISTING_AND_PPS_INCREASING1.264", "wb");
549 #endif
550 
551   // Test part#1
552   // step#1: pParam1
553   //int TraceLevel = WELS_LOG_INFO;
554   //encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
555   int rv = encoder_->InitializeExt (&sParam1);
556   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
557                                       sParam1.iPicHeight;
558   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
559 
560   // new IDR
561   rv = encoder_->ForceIntraFrame (true);
562   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
563   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
564 
565   // step#2: pParam2
566   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
567   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam2.iPicWidth << "x" <<
568                                       sParam2.iPicHeight;
569   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
570 
571   // new IDR
572   rv = encoder_->ForceIntraFrame (true);
573   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
574   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
575 
576   // step#3: back to pParam1
577   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
578   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
579                                       sParam1.iPicHeight;
580   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
581 
582   // step#4: back to pParam2
583   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
584   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv << sParam2.iPicWidth << sParam2.iPicHeight;
585   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
586 
587 #ifdef DEBUG_FILE_SAVE2
588   fclose (fEnc);
589 #endif
590   rv = encoder_->Uninitialize();
591   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
592 
593   // Test part#2
594   // step#1: pParam1
595   rv = encoder_->InitializeExt (&sParam1);
596   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt Failed: rv = " << rv;
597   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
598   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
599   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam3);
600   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam3: rv = " << rv;
601 
602 #ifdef DEBUG_FILE_SAVE2
603   fEnc = fopen ("enc_SPS_LISTING_AND_PPS_INCREASING11.264", "wb");
604 #endif
605   iEncFrameNum = 0;
606   ASSERT_TRUE (EncDecOneFrame (sParam3.iPicWidth, sParam3.iPicHeight, iEncFrameNum++, fEnc));
607 
608   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
609   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
610   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
611 
612   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
613   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
614   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
615 
616 #ifdef DEBUG_FILE_SAVE2
617   fclose (fEnc);
618 #endif
619   rv = encoder_->Uninitialize();
620   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
621 }
622 
623 //#define DEBUG_FILE_SAVE5
TEST_F(EncodeDecodeTestAPI,ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING2)624 TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING2) {
625   //usage 3: 2 Params with different num_ref, encode IDR0, P1, IDR2;
626   //the bs will show two SPS and different PPS
627 
628   int iWidth       = GetRandWidth();
629   int iHeight      = GetRandHeight();
630   float fFrameRate = rand() + 0.5f;
631   int iEncFrameNum = 0;
632   int iSpatialLayerNum = 1;
633   int iSliceNum        = 1;
634 
635   // prepare params
636   SEncParamExt   sParam1;
637   SEncParamExt   sParam2;
638   encoder_->GetDefaultParams (&sParam1);
639   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
640   sParam1.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
641   sParam1.iTemporalLayerNum = 1;
642   //prepare param2
643   memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
644   prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
645   sParam2.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
646   sParam2.iTemporalLayerNum = 3;
647 
648   //prepare output if needed
649   FILE* fEnc =  NULL;
650 #ifdef DEBUG_FILE_SAVE5
651   fEnc = fopen ("enc_SPS_LISTING_AND_PPS_INCREASING2.264", "wb");
652 #endif
653 
654   // step#1: pParam1
655   int rv = encoder_->InitializeExt (&sParam1);
656   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
657                                       sParam1.iPicHeight;
658 
659   // step#2: pParam2
660   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
661   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
662 
663   // step#3: set back to pParam1, with a smaller num_ref, it still uses the previous SPS
664   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
665   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam1: rv = " << rv;
666   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
667 
668   // new IDR, PPS increases
669   rv = encoder_->ForceIntraFrame (true);
670   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
671   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
672 
673   rv = encoder_->Uninitialize();
674   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
675 
676 #ifdef DEBUG_FILE_SAVE5
677   fclose (fEnc);
678 #endif
679 }
680 
TEST_F(EncodeDecodeTestAPI,ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING3)681 TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING3) {
682 
683   int iWidth       = GetRandWidth();
684   int iHeight      = GetRandHeight();
685   float fFrameRate = rand() + 0.5f;
686   int iEncFrameNum = 0;
687   int iSpatialLayerNum = 1;
688   int iSliceNum        = 1;
689 
690   // prepare params
691   SEncParamExt   sParam1;
692   SEncParamExt   sParam2;
693   encoder_->GetDefaultParams (&sParam1);
694   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
695   sParam1.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
696 
697   //prepare output if needed
698   FILE* fEnc =  NULL;
699 #ifdef DEBUG_FILE_SAVE2
700   fEnc = fopen ("enc_SPS_LISTING_AND_PPS_INCREASING3.264", "wb");
701 #endif
702 
703   // step#1: pParam1
704   int rv = encoder_->InitializeExt (&sParam1);
705   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt Failed: rv = " << rv;
706 
707   int max_count = 65; // make it more then twice as MAX_SPS_COUNT
708   std::vector<int> vWidthTable;
709   vWidthTable.push_back (GET_MB_WIDTH (sParam1.iPicWidth));
710 
711   std::vector<int>::iterator vWidthTableIt;
712   for (int times = 0; times < max_count; times++) {
713     //prepare param2
714     memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
715     do {
716       sParam2.iPicWidth = GetRandWidth();
717       vWidthTableIt = std::find (vWidthTable.begin(), vWidthTable.end(), GET_MB_WIDTH (sParam2.iPicWidth));
718     } while (vWidthTableIt != vWidthTable.end());
719     vWidthTable.push_back (GET_MB_WIDTH (sParam2.iPicWidth));
720     prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
721     sParam2.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
722 
723     rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
724     ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv << ", sParam2.iPicWidth=" <<
725                                         sParam2.iPicWidth;
726   } // end of setting loop
727 
728   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
729 
730 #ifdef DEBUG_FILE_SAVE2
731   fclose (fEnc);
732 #endif
733   rv = encoder_->Uninitialize();
734   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
735 }
736 
737 //#define DEBUG_FILE_SAVE6
TEST_F(EncodeDecodeTestAPI,ParameterSetStrategy_SPS_PPS_LISTING1)738 TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING1) {
739   //usage 1: 1 resolution Params, encode IDR0, P1, IDR2;
740   //the bs will show same SPS and different PPS
741   // PPS: pic_parameter_set_id                                     1 (  0)
742   // PPS: seq_parameter_set_id                                     1 (  0)
743   // PPS: pic_parameter_set_id                                   010 (  1)
744   // PPS: seq_parameter_set_id                                     1 (  0)
745   // SH: slice_type                                              011 (  2)
746   // SH: pic_parameter_set_id                                      1 (  0)
747   // SH: slice_type                                                1 (  0)
748   // SH: pic_parameter_set_id                                      1 (  0)
749   // SH: slice_type                                              011 (  2)
750   // SH: pic_parameter_set_id                                    010 (  1)
751   int iWidth       = GetRandWidth();
752   int iHeight      = GetRandHeight();
753   float fFrameRate = rand() + 0.5f;
754   int iEncFrameNum = 0;
755   int iSpatialLayerNum = 1;
756   int iSliceNum        = 1;
757 
758   // prepare params
759   SEncParamExt   sParam1;
760   encoder_->GetDefaultParams (&sParam1);
761   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
762   sParam1.eSpsPpsIdStrategy = SPS_PPS_LISTING;
763 
764   //prepare output if needed
765   FILE* fEnc =  NULL;
766 #ifdef DEBUG_FILE_SAVE6
767   fEnc = fopen ("encLIST1.264", "wb");
768 #endif
769 
770   // step#1: pParam1
771   int rv = encoder_->InitializeExt (&sParam1);
772   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
773                                       sParam1.iPicHeight;
774   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
775   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
776 
777   // new IDR
778   rv = encoder_->ForceIntraFrame (true);
779   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
780   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
781 
782   rv = encoder_->Uninitialize();
783   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
784 
785 #ifdef DEBUG_FILE_SAVE6
786   fclose (fEnc);
787 #endif
788 }
789 
TEST_F(EncodeDecodeTestAPI,ParameterSetStrategy_SPS_PPS_LISTING2)790 TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING2) {
791   //usage 2: 2 resolution Params, encode IDR0, IDR1, IDR2;
792   //the bs will show two SPS and different PPS
793   // === SPS LIST ===
794   //SPS: seq_parameter_set_id                                     1 (  0) -- PARAM1
795   //SPS: seq_parameter_set_id                                   010 (  1) -- PARAM2
796   // === PPS LIST ===
797   //PPS: pic_parameter_set_id                                     1 (  0)
798   //PPS: seq_parameter_set_id                                     1 (  0)
799   //PPS: pic_parameter_set_id                                   010 (  1)
800   //PPS: seq_parameter_set_id                                   010 (  1)
801   //PPS: pic_parameter_set_id                                   011 (  2) -- PPS2 - SPS0
802   //PPS: seq_parameter_set_id                                     1 (  0)
803   //PPS: pic_parameter_set_id                                 00100 (  3) -- PPS3 - SPS1
804   //PPS: seq_parameter_set_id                                   010 (  1)
805   //PPS: pic_parameter_set_id                                 00101 (  4) -- PPS4 - SPS0
806   //PPS: seq_parameter_set_id                                     1 (  0)
807   // === VCL LAYER ===
808   //SH: slice_type                                              011 (  2) -- PARAM2
809   //SH: pic_parameter_set_id                                    010 (  1) -- PPS1 - SPS1 - PARAM2
810   //SH: slice_type                                              011 (  2) -- PARAM1
811   //SH: pic_parameter_set_id                                    011 (  2) -- PPS2 - SPS0 - PARAM1
812   //SH: slice_type                                             011 (  2) -- PARAM1
813   //SH: pic_parameter_set_id                                 00101 (  4) -- PPS4 - SPS0 - PARAM1
814 
815   int iWidth       = GetRandWidth();
816   int iHeight      = GetRandHeight();
817   float fFrameRate = rand() + 0.5f;
818   int iEncFrameNum = 0;
819   int iSpatialLayerNum = 1;
820   int iSliceNum        = 1;
821 
822   // prepare params
823   SEncParamExt   sParam1;
824   SEncParamExt   sParam2;
825   encoder_->GetDefaultParams (&sParam1);
826   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
827   sParam1.eSpsPpsIdStrategy = SPS_PPS_LISTING;
828   //prepare param2
829   memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
830   while (GET_MB_WIDTH (sParam2.iPicWidth) == GET_MB_WIDTH (sParam1.iPicWidth)) {
831     sParam2.iPicWidth = GetRandWidth();
832   }
833   prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
834   sParam2.eSpsPpsIdStrategy = SPS_PPS_LISTING;
835 
836   //prepare output if needed
837   FILE* fEnc =  NULL;
838 #ifdef DEBUG_FILE_SAVE5
839   fEnc = fopen ("encLIST2.264", "wb");
840 #endif
841 
842   // step#1: pParam1
843   int rv = encoder_->InitializeExt (&sParam1);
844   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
845                                       sParam1.iPicHeight;
846 
847   // step#2: pParam2
848   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
849   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
850   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
851 
852   // step#3: back to pParam1, SHOULD NOT encounter ERROR
853   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
854   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
855                                       sParam1.iPicHeight;
856   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
857 
858   // new IDR
859   rv = encoder_->ForceIntraFrame (true);
860   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
861   ASSERT_TRUE (EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc));
862 
863   rv = encoder_->Uninitialize();
864   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
865 
866 #ifdef DEBUG_FILE_SAVE5
867   fclose (fEnc);
868 #endif
869 }
870 
TEST_F(EncodeDecodeTestAPI,ParameterSetStrategy_SPS_PPS_LISTING3)871 TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING3) {
872 
873   int iWidth       = GetRandWidth();
874   int iHeight      = GetRandHeight();
875   float fFrameRate = rand() + 0.5f;
876   int iEncFrameNum = 0;
877   int iSpatialLayerNum = 1;
878   int iSliceNum        = 1;
879 
880   // prepare params
881   SEncParamExt   sParam1;
882   SEncParamExt   sParam2;
883   SEncParamExt   sParam3;
884   encoder_->GetDefaultParams (&sParam1);
885   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
886   sParam1.eSpsPpsIdStrategy = SPS_PPS_LISTING;
887   //prepare param2
888   memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
889   while (GET_MB_WIDTH (sParam2.iPicWidth) == GET_MB_WIDTH (sParam1.iPicWidth)) {
890     sParam2.iPicWidth = GetRandWidth();
891   }
892   prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
893   sParam2.eSpsPpsIdStrategy = SPS_PPS_LISTING;
894   //prepare param3
895   memcpy (&sParam3, &sParam1, sizeof (SEncParamExt));
896   while (GET_MB_WIDTH (sParam3.iPicWidth) == GET_MB_WIDTH (sParam1.iPicWidth) ||
897          GET_MB_WIDTH (sParam3.iPicWidth) == GET_MB_WIDTH (sParam2.iPicWidth)) {
898     sParam3.iPicWidth = GetRandWidth();
899   }
900   prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam3.iPicWidth, sParam3.iPicHeight, fFrameRate, &sParam3);
901   sParam3.eSpsPpsIdStrategy = SPS_PPS_LISTING;
902 
903   //prepare output if needed
904   FILE* fEnc =  NULL;
905 #ifdef DEBUG_FILE_SAVE5
906   fEnc = fopen ("enc_LISTING3.264", "wb");
907 #endif
908 
909   // step#1: ordinary encoding
910   int rv = encoder_->InitializeExt (&sParam1);
911   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
912                                       sParam1.iPicHeight;
913   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
914   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
915   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
916 
917   // step#2: set strategy for success
918   int32_t iNewStra = SPS_PPS_LISTING;
919   rv = encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iNewStra);
920   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv << " iNewStra=" << iNewStra;
921 
922   // step#3: setting new strategy, SHOULD encounter ERROR
923   unsigned int TraceLevel = WELS_LOG_QUIET;
924   rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
925   ASSERT_TRUE (rv == cmResultSuccess);
926   iNewStra = CONSTANT_ID;
927   rv = encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iNewStra);
928   ASSERT_TRUE (rv != cmResultSuccess);
929 
930   ASSERT_TRUE (EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc));
931 
932   // step#4: pParam3, SHOULD encounter ERROR
933   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam3);
934   ASSERT_TRUE (rv != cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam3.iPicWidth << "x" <<
935                                       sParam3.iPicHeight;
936 
937   rv = encoder_->Uninitialize();
938   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
939 
940 #ifdef DEBUG_FILE_SAVE5
941   fclose (fEnc);
942 #endif
943 }
944 
945 
TEST_F(EncodeDecodeTestAPI,SimulcastSVC)946 TEST_F (EncodeDecodeTestAPI, SimulcastSVC) {
947   int iSpatialLayerNum = WelsClip3 ((rand() % MAX_SPATIAL_LAYER_NUM), 2, MAX_SPATIAL_LAYER_NUM);
948   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 16, MAX_WIDTH);
949   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 16, MAX_HEIGHT);
950   float fFrameRate = rand() + 0.5f;
951   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
952   int iSliceNum        = 1;
953   encoder_->GetDefaultParams (&param_);
954   prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
955 
956   int rv = encoder_->InitializeExt (&param_);
957   ASSERT_TRUE (rv == cmResultSuccess);
958 
959   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
960   int aLen[MAX_SPATIAL_LAYER_NUM] = {0};
961   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
962 
963 #ifdef DEBUG_FILE_SAVE2
964   FILE* fEnc[MAX_SPATIAL_LAYER_NUM] = { NULL };
965   fEnc[0] = fopen ("enc0.264", "wb");
966   fEnc[1] = fopen ("enc1.264", "wb");
967   fEnc[2] = fopen ("enc2.264", "wb");
968   fEnc[3] = fopen ("enc3.264", "wb");
969 #endif
970 
971   // init decoders
972   int iIdx = 0;
973   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
974     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
975     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
976     aLen[iIdx] = 0;
977 
978     long rv = WelsCreateDecoder (&decoder[iIdx]);
979     ASSERT_EQ (0, rv);
980     ASSERT_TRUE (decoder[iIdx] != NULL);
981 
982     SDecodingParam decParam;
983     memset (&decParam, 0, sizeof (SDecodingParam));
984     decParam.uiTargetDqLayer = UCHAR_MAX;
985     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
986     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
987 
988     rv = decoder[iIdx]->Initialize (&decParam);
989     ASSERT_EQ (0, rv);
990   }
991 
992   for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
993     int iResult;
994     int iLayerLen = 0;
995     unsigned char* pData[3] = { NULL };
996 
997     ASSERT_TRUE (InitialEncDec (param_.iPicWidth, param_.iPicHeight));
998     EncodeOneFrame (0);
999 
1000     iLayerLen = 0;
1001     for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1002       aLen[iIdx] = 0;
1003     }
1004     for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
1005       iLayerLen = 0;
1006       const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
1007       for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
1008         iLayerLen += layerInfo.pNalLengthInByte[iNal];
1009       }
1010 
1011       if (layerInfo.uiLayerType == NON_VIDEO_CODING_LAYER) {
1012         // under SimulcastSVC, need to copy non-VCL to all layers
1013         for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1014           memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
1015           aLen[iIdx] += iLayerLen;
1016         }
1017       } else {
1018         iIdx = layerInfo.uiSpatialId;
1019         EXPECT_TRUE (iIdx < iSpatialLayerNum);
1020         memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
1021         aLen[iIdx] += iLayerLen;
1022       }
1023     }
1024 
1025     for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1026       pData[0] = pData[1] = pData[2] = 0;
1027       memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
1028 
1029 #ifdef DEBUG_FILE_SAVE2
1030       fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
1031 #endif
1032       iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
1033       EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
1034       iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
1035       EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
1036       if (dstBufInfo_.iBufferStatus == 0) {
1037         int32_t num_of_frames_in_buffer = 0;
1038         decoder[iIdx]->GetOption (DECODER_OPTION_NUM_OF_FRAMES_REMAINING_IN_BUFFER, &num_of_frames_in_buffer);
1039         for (int32_t i = 0; i < num_of_frames_in_buffer; ++i) {
1040           decoder[iIdx]->FlushFrame (pData, &dstBufInfo_);
1041         }
1042       }
1043       EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
1044     }
1045   }
1046 
1047   // free all
1048   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1049     if (pBsBuf[iIdx]) {
1050       free (pBsBuf[iIdx]);
1051     }
1052 
1053     if (decoder[iIdx] != NULL) {
1054       decoder[iIdx]->Uninitialize();
1055       WelsDestroyDecoder (decoder[iIdx]);
1056     }
1057 
1058 #ifdef DEBUG_FILE_SAVE2
1059     fclose (fEnc[iIdx]);
1060 #endif
1061   }
1062 
1063 }
1064 
TEST_F(EncodeDecodeTestAPI,SimulcastAVC)1065 TEST_F (EncodeDecodeTestAPI, SimulcastAVC) {
1066 //#define DEBUG_FILE_SAVE3
1067   int iSpatialLayerNum = WelsClip3 ((rand() % MAX_SPATIAL_LAYER_NUM), 2, MAX_SPATIAL_LAYER_NUM);
1068   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 16, MAX_WIDTH);
1069   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 16, MAX_HEIGHT);
1070   float fFrameRate = rand() + 0.5f;
1071   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1072   int iSliceNum        = 1;
1073   encoder_->GetDefaultParams (&param_);
1074   prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
1075 
1076   //set flag of bSimulcastAVC
1077   param_.bSimulcastAVC = true;
1078 
1079   int rv = encoder_->InitializeExt (&param_);
1080   ASSERT_TRUE (rv == cmResultSuccess);
1081 
1082   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1083   int aLen[MAX_SPATIAL_LAYER_NUM] = {0};
1084   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1085 
1086 #ifdef DEBUG_FILE_SAVE3
1087   FILE* fEnc[MAX_SPATIAL_LAYER_NUM];
1088   fEnc[0] = fopen ("enc0.264", "wb");
1089   fEnc[1] = fopen ("enc1.264", "wb");
1090   fEnc[2] = fopen ("enc2.264", "wb");
1091   fEnc[3] = fopen ("enc3.264", "wb");
1092 #endif
1093 
1094   int iIdx = 0;
1095 
1096   //create decoder
1097   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1098     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1099     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1100     aLen[iIdx] = 0;
1101 
1102     long rv = WelsCreateDecoder (&decoder[iIdx]);
1103     ASSERT_EQ (0, rv);
1104     ASSERT_TRUE (decoder[iIdx] != NULL);
1105 
1106     SDecodingParam decParam;
1107     memset (&decParam, 0, sizeof (SDecodingParam));
1108     decParam.uiTargetDqLayer = UCHAR_MAX;
1109     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1110     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1111 
1112     rv = decoder[iIdx]->Initialize (&decParam);
1113     ASSERT_EQ (0, rv);
1114   }
1115 
1116   iEncFrameNum = 10;
1117   for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
1118     int iResult;
1119     int iLayerLen = 0;
1120     unsigned char* pData[3] = { NULL };
1121 
1122     ASSERT_TRUE (InitialEncDec (param_.iPicWidth, param_.iPicHeight));
1123     EncodeOneFrame (0);
1124 
1125     // init
1126     for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1127       aLen[iIdx] = 0;
1128     }
1129     for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
1130       iLayerLen = 0;
1131       const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
1132       const int kiFirstNalType = ((* (layerInfo.pBsBuf + 4)) & 0x1f);
1133       ASSERT_TRUE ((kiFirstNalType == NAL_SPS) || (kiFirstNalType == NAL_PPS) || (kiFirstNalType == NAL_SLICE)
1134                    || (kiFirstNalType == NAL_SLICE_IDR) || (kiFirstNalType == NAL_SEI));
1135       for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
1136         iLayerLen += layerInfo.pNalLengthInByte[iNal];
1137       }
1138 
1139       iIdx = layerInfo.uiSpatialId;
1140       EXPECT_TRUE (iIdx < iSpatialLayerNum);
1141       memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
1142       aLen[iIdx] += iLayerLen;
1143     }
1144 
1145     for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1146       pData[0] = pData[1] = pData[2] = 0;
1147       memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
1148 
1149 #ifdef DEBUG_FILE_SAVE3
1150       fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
1151 #endif
1152       iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
1153       EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
1154 
1155       iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
1156       EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
1157       EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
1158     }
1159   }
1160 
1161   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1162     free (pBsBuf[iIdx]);
1163 
1164     if (decoder[iIdx] != NULL) {
1165       decoder[iIdx]->Uninitialize();
1166       WelsDestroyDecoder (decoder[iIdx]);
1167     }
1168   }
1169 #ifdef DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1170   for (int i = 0; i <)MAX_SPATIAL_LAYER_NUM;
1171   i++) {
1172     fclose (fEnc[i]);
1173   }
1174 #endif
1175 }
1176 
TEST_F(EncodeDecodeTestAPI,SimulcastAVC_SPS_PPS_LISTING)1177 TEST_F (EncodeDecodeTestAPI, SimulcastAVC_SPS_PPS_LISTING) {
1178   int iSpatialLayerNum = WelsClip3 ((rand() % MAX_SPATIAL_LAYER_NUM), 2, MAX_SPATIAL_LAYER_NUM);;
1179   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
1180   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
1181   float fFrameRate = rand() + 0.5f;
1182   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1183   int iSliceNum        = 1;
1184   iWidth = VALID_SIZE (iWidth);
1185   iHeight = VALID_SIZE (iHeight);
1186   // prepare params
1187   SEncParamExt   sParam1;
1188   SEncParamExt   sParam2;
1189   encoder_->GetDefaultParams (&sParam1);
1190   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
1191   //set flag of SPS_PPS_LISTING
1192   sParam1.eSpsPpsIdStrategy = SPS_PPS_LISTING;//SPS_LISTING;//
1193   //set flag of bSimulcastAVC
1194   sParam1.bSimulcastAVC = true;
1195   //prepare param2
1196   memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
1197   sParam2.sSpatialLayers[0].iVideoWidth = (sParam1.sSpatialLayers[0].iVideoWidth / 2);
1198   sParam2.sSpatialLayers[0].iVideoHeight = (sParam1.sSpatialLayers[0].iVideoHeight / 2);
1199 
1200   int rv = encoder_->InitializeExt (&sParam1);
1201   ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam1: rv = " << rv;;
1202   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
1203   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
1204 
1205   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1206   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1207 
1208   int iIdx = 0;
1209 
1210   //create decoder
1211   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1212     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1213     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1214 
1215     long rv = WelsCreateDecoder (&decoder[iIdx]);
1216     ASSERT_EQ (0, rv);
1217     ASSERT_TRUE (decoder[iIdx] != NULL);
1218 
1219     SDecodingParam decParam;
1220     memset (&decParam, 0, sizeof (SDecodingParam));
1221     decParam.uiTargetDqLayer = UCHAR_MAX;
1222     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1223     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1224 
1225     rv = decoder[iIdx]->Initialize (&decParam);
1226     ASSERT_EQ (0, rv);
1227   }
1228 
1229   ASSERT_TRUE (TestOneSimulcastAVC (&sParam1, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0));
1230   ASSERT_TRUE (TestOneSimulcastAVC (&sParam2, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0));
1231 
1232   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1233     free (pBsBuf[iIdx]);
1234 
1235     if (decoder[iIdx] != NULL) {
1236       decoder[iIdx]->Uninitialize();
1237       WelsDestroyDecoder (decoder[iIdx]);
1238     }
1239 
1240   }
1241 }
1242 
1243 struct EncodeOptionParam {
1244   bool bTestNalSize;
1245   bool bAllRandom;
1246   bool bTestDecoder;
1247   int iNumframes;
1248   int iWidth;
1249   int iHeight;
1250   int iQp;
1251   SliceModeEnum eSliceMode;
1252   int uiMaxNalLen;
1253   float fFramerate;
1254   int iThreads;
1255   const char* sFileSave;
1256 };
1257 
1258 static const EncodeOptionParam kOptionParamArray[] = {
1259   {true, true, false, 30, 600, 460, 1, SM_SIZELIMITED_SLICE, 450, 15.0, 1, ""},
1260   {true, true, false, 30, 340, 96, 24, SM_SIZELIMITED_SLICE, 1000, 30.0, 1, ""},
1261   {true, true, false, 30, 140, 196, 51, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1262   {true, true, false, 30, 110, 296, 50, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1263   {true, true, false, 30, 104, 416, 44, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1264   {true, true, false, 30, 16, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""}, //5
1265   {true, false, true, 30, 600, 460, 1, SM_SIZELIMITED_SLICE, 450, 15.0, 1, ""},
1266   {true, false, true, 30, 340, 96, 24, SM_SIZELIMITED_SLICE, 1000, 30.0, 1, ""},
1267   {true, false, true, 30, 140, 196, 51, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1268   {true, false, true, 30, 110, 296, 50, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1269   {true, false, true, 30, 104, 416, 44, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""}, //10
1270   {true, false, true, 30, 16, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1271   {true, true, true, 30, 600, 460, 1, SM_SIZELIMITED_SLICE, 450, 15.0, 1, ""},
1272   {true, true, true, 30, 340, 96, 24, SM_SIZELIMITED_SLICE, 1000, 30.0, 1, ""},
1273   {true, true, true, 30, 140, 196, 51, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1274   {true, true, true, 30, 110, 296, 50, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""}, //15
1275   {true, true, true, 30, 104, 416, 44, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1276   {true, true, true, 30, 16, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1277   {false, true, false, 30, 32, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1278   {false, true, false, 30, 600, 460, 1, SM_SIZELIMITED_SLICE, 450, 15.0, 4, ""},
1279   {false, true, false, 30, 340, 96, 24, SM_SIZELIMITED_SLICE, 1000, 30.0, 2, ""}, //20
1280   {false, true, false, 30, 140, 196, 51, SM_SIZELIMITED_SLICE, 500, 7.5, 3, ""},
1281   {false, true, false, 30, 110, 296, 50, SM_SIZELIMITED_SLICE, 500, 7.5, 2, ""},
1282   {false, true, false, 30, 104, 416, 44, SM_SIZELIMITED_SLICE, 500, 7.5, 2, ""},
1283   {false, true, false, 30, 16, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 3, ""},
1284   {false, true, false, 30, 32, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 3, ""}, //25
1285   {false, false, true, 30, 600, 460, 1, SM_FIXEDSLCNUM_SLICE, 0, 15.0, 4, ""},
1286   {false, false, true, 30, 600, 460, 1, SM_FIXEDSLCNUM_SLICE, 0, 15.0, 8, ""},
1287   //for large size tests
1288   {true, false, true, 2, 4096, 2304, 1, SM_RESERVED, 0, 7.5, 1, ""}, // large picture size, //28
1289   {true, false, true, 2, 2304, 4096, 1, SM_RESERVED, 0, 15.0, 1, ""}, //29
1290   {true, false, true, 2, 3072, 3072, 1, SM_RESERVED, 0, 15.0, 1, ""}, //30
1291   //{true, false, true, 2, 3072, 3072, 1, SM_RESERVED, 0, 15.0, 4, ""}, //14760
1292   {false, false, true, 2, 1072, 8576, 1, SM_RESERVED, 0, 15.0, 1, ""},
1293   {false, false, true, 2, 8576, 1072, 24, SM_SINGLE_SLICE, 0, 15.0, 1, ""}, //14754
1294   //{false, false, false, 2, 8576, 1088, 24, SM_SINGLE_SLICE, 0, 15.0, 1, ""}, //14755
1295   //{false, false, false, 2, 1088, 8576, 24, SM_SINGLE_SLICE, 0, 15.0, 1, ""}, //14755
1296   {false, false, true, 2, 8688, 1072, 24, SM_SINGLE_SLICE, 0, 15.0, 1, ""}, //Annex A: PicWidthInMbs <= sqrt(36864*8) = 543; 543*16=8688; 36864/543=67; 67*16=1072
1297   {false, false, true, 2, 1072, 8688, 24, SM_SINGLE_SLICE, 0, 15.0, 1, ""}, //Annex A: FrameHeightInMbs <= sqrt(36864*8) = 543; 543*16=8688; 36864/543=67; 67*16=1072
1298   //{false, false, true, 2, 589824, 16, 24, SM_RESERVED, 0, 15.0, 1, ""},
1299   //{false, false, true, 2, 589824, 16, 24, SM_RESERVED, 0, 15.0, 1, ""},
1300 };
1301 
1302 class EncodeTestAPI : public ::testing::TestWithParam<EncodeOptionParam>, public ::EncodeDecodeTestAPIBase {
1303  public:
SetUp()1304   void SetUp() {
1305     EncodeDecodeTestAPIBase::SetUp();
1306   }
1307 
TearDown()1308   void TearDown() {
1309     EncodeDecodeTestAPIBase::TearDown();
1310   }
EncodeOneFrameRandom(int iCheckTypeIndex,bool bAllRandom)1311   void EncodeOneFrameRandom (int iCheckTypeIndex, bool bAllRandom) {
1312     int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
1313     uint8_t* ptr = buf_.data();
1314     uint8_t uiVal = rand() % 256;
1315     for (int i = 0; i < frameSize; i++) {
1316       ptr[i] = bAllRandom ? (rand() % 256) : uiVal;
1317     }
1318     int rv = encoder_->EncodeFrame (&EncPic, &info);
1319     if (0 == iCheckTypeIndex) {
1320       ASSERT_TRUE (rv == cmResultSuccess) << "rv=" << rv;
1321     } else if (1 == iCheckTypeIndex) {
1322       ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnknownReason) << "rv=" << rv;
1323     }
1324   }
1325 };
1326 
1327 INSTANTIATE_TEST_CASE_P (EncodeDecodeTestAPIBase, EncodeTestAPI,
1328                          ::testing::ValuesIn (kOptionParamArray));
1329 
TEST_P(EncodeTestAPI,SetEncOptionSize)1330 TEST_P (EncodeTestAPI, SetEncOptionSize) {
1331   EncodeOptionParam p = GetParam();
1332   memset (&param_, 0, sizeof (SEncParamExt));
1333   encoder_->GetDefaultParams (&param_);
1334   param_.uiMaxNalSize = p.uiMaxNalLen;
1335   param_.iTemporalLayerNum = (rand() % 4) + 1;
1336   param_.iSpatialLayerNum = 1;
1337   param_.iUsageType = CAMERA_VIDEO_REAL_TIME;
1338   param_.iPicWidth = p.iWidth;
1339   param_.iPicHeight = p.iHeight;
1340   param_.fMaxFrameRate = p.fFramerate;
1341   param_.iRCMode = RC_OFF_MODE; //rc off
1342   param_.iMultipleThreadIdc = p.iThreads;
1343   param_.iNumRefFrame = AUTO_REF_PIC_COUNT;
1344   param_.sSpatialLayers[0].iVideoWidth = p.iWidth;
1345   param_.sSpatialLayers[0].iVideoHeight = p.iHeight;
1346   param_.sSpatialLayers[0].fFrameRate = p.fFramerate;
1347 
1348   int iSliceModeTestNum = 1;
1349   if (SM_RESERVED == p.eSliceMode) {
1350     iSliceModeTestNum = SLICE_MODE_NUM;
1351   }
1352 
1353   for (int iSliceIdx = 0; iSliceIdx < iSliceModeTestNum; iSliceIdx++) {
1354     if (1 == iSliceModeTestNum) {
1355       param_.sSpatialLayers[0].sSliceArgument.uiSliceMode = p.eSliceMode;
1356     } else {
1357       param_.sSpatialLayers[0].sSliceArgument.uiSliceMode = static_cast<SliceModeEnum> (iSliceIdx);
1358     }
1359 
1360     FILE* pFile = NULL;
1361     if (p.sFileSave != NULL && strlen (p.sFileSave) > 0) {
1362       pFile = fopen (p.sFileSave, "wb");
1363     }
1364 
1365     if (SM_FIXEDSLCNUM_SLICE == param_.sSpatialLayers[0].sSliceArgument.uiSliceMode) {
1366       param_.sSpatialLayers[0].sSliceArgument.uiSliceNum = 8;
1367     } else if (SM_RASTER_SLICE == param_.sSpatialLayers[0].sSliceArgument.uiSliceMode) {
1368       param_.sSpatialLayers[0].sSliceArgument.uiSliceMbNum[0] =
1369         param_.sSpatialLayers[0].sSliceArgument.uiSliceMbNum[1] =
1370           param_.sSpatialLayers[0].sSliceArgument.uiSliceMbNum[2] =
1371             param_.sSpatialLayers[0].sSliceArgument.uiSliceMbNum[3] = ((p.iWidth * p.iHeight) >> 10);
1372     } else if (SM_SIZELIMITED_SLICE == param_.sSpatialLayers[0].sSliceArgument.uiSliceMode && 450 > p.uiMaxNalLen) {
1373       param_.uiMaxNalSize = 450;
1374       param_.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = 450;
1375     }
1376 
1377     int32_t iTraceLevel = WELS_LOG_QUIET;
1378     encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1379     decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1380 
1381     encoder_->Uninitialize();
1382     int rv = encoder_->InitializeExt (&param_);
1383     ASSERT_TRUE (rv == cmResultSuccess);
1384     ASSERT_TRUE (InitialEncDec (p.iWidth, p.iHeight));
1385 
1386     int32_t iSpsPpsIdAddition = 1;
1387     encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
1388     int32_t iIDRPeriod = (int32_t) pow (2.0f, (param_.iTemporalLayerNum - 1)) * ((rand() % 5) + 1);
1389     encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
1390     int iIdx = 0;
1391     int iLen;
1392     unsigned char* pData[3] = { NULL };
1393 
1394     //FIXME: remove this after the multi-thread case is correctly handled in encoder
1395     if (p.iThreads > 1 && SM_SIZELIMITED_SLICE == p.eSliceMode) {
1396       p.bAllRandom = false;
1397     }
1398 
1399     while (iIdx <= p.iNumframes) {
1400       EncodeOneFrameRandom (0, p.bAllRandom);
1401       encToDecData (info, iLen);
1402       if (pFile) {
1403         fwrite (info.sLayerInfo[0].pBsBuf, iLen, 1, pFile);
1404         fflush (pFile);
1405       }
1406       memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
1407       if (iLen && p.bTestDecoder) {
1408         rv = decoder_->DecodeFrameNoDelay (info.sLayerInfo[0].pBsBuf, iLen, pData, &dstBufInfo_);
1409         ASSERT_EQ (rv, 0);
1410         ASSERT_EQ (dstBufInfo_.iBufferStatus, 1);
1411       }
1412       int iLayer = 0;
1413       while (iLayer < info.iLayerNum) {
1414         SLayerBSInfo* pLayerBsInfo = &info.sLayerInfo[iLayer];
1415         if (pLayerBsInfo != NULL) {
1416           int iNalIdx = WELS_MAX (pLayerBsInfo->iNalCount - 2, 0); // ignore last slice under single slice mode
1417           do {
1418             if (SM_SIZELIMITED_SLICE == p.eSliceMode
1419                 && p.bTestNalSize) { // ignore the case that 2 MBs in one picture, and the multithreads case, enable them when code is ready
1420               ASSERT_GE (((int)param_.uiMaxNalSize), pLayerBsInfo->pNalLengthInByte[iNalIdx]);
1421             }
1422             -- iNalIdx;
1423           } while (iNalIdx >= 0);
1424         }
1425         ++ iLayer;
1426       }
1427       iIdx++;
1428     }
1429     if (pFile) {
1430       fclose (pFile);
1431     }
1432   }
1433 }
1434 
1435 
1436 
TEST_F(EncodeDecodeTestAPI,SimulcastAVCDiffFps)1437 TEST_F (EncodeDecodeTestAPI, SimulcastAVCDiffFps) {
1438 //#define DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1439   int iSpatialLayerNum = WelsClip3 ((rand() % MAX_SPATIAL_LAYER_NUM), 2, MAX_SPATIAL_LAYER_NUM);
1440   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
1441   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
1442   iWidth = VALID_SIZE (iWidth);
1443   iHeight = VALID_SIZE (iHeight);
1444 
1445   float fFrameRate = 30;
1446   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1447   int iSliceNum        = 1;
1448   encoder_->GetDefaultParams (&param_);
1449   prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
1450 
1451   //set flag of bSimulcastAVC
1452   param_.bSimulcastAVC = true;
1453   param_.iTemporalLayerNum = (rand() % 2) ? 3 : 4;
1454 
1455   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1456   int aLen[MAX_SPATIAL_LAYER_NUM] = {0};
1457   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1458 
1459 #ifdef DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1460   FILE* fEnc[MAX_SPATIAL_LAYER_NUM];
1461   fEnc[0] = fopen ("enc0.264", "wb");
1462   fEnc[1] = fopen ("enc1.264", "wb");
1463   fEnc[2] = fopen ("enc2.264", "wb");
1464   fEnc[3] = fopen ("enc3.264", "wb");
1465 #endif
1466 
1467   int iIdx = 0;
1468 
1469   //create decoder
1470   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1471     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1472     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1473     aLen[iIdx] = 0;
1474 
1475     long rv = WelsCreateDecoder (&decoder[iIdx]);
1476     ASSERT_EQ (0, rv);
1477     ASSERT_TRUE (decoder[iIdx] != NULL);
1478 
1479     SDecodingParam decParam;
1480     memset (&decParam, 0, sizeof (SDecodingParam));
1481     decParam.uiTargetDqLayer = UCHAR_MAX;
1482     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1483     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1484 
1485     rv = decoder[iIdx]->Initialize (&decParam);
1486     ASSERT_EQ (0, rv);
1487   }
1488 
1489 #define PATTERN_NUM (18)
1490   const int32_t iTemporalPattern[PATTERN_NUM][MAX_SPATIAL_LAYER_NUM] = { {2, 1, 1, 1}, {2, 2, 2, 1}, {4, 1, 1, 1}, {4, 2, 1, 1},
1491     {1, 2, 1, 1}, {1, 1, 2, 1}, {1, 4, 1, 1}, {2, 4, 2, 1}, {1, 4, 2, 1}, {1, 4, 4, 1},
1492     {1, 2, 2, 1}, {2, 1, 2, 1}, {1, 2, 4, 1},
1493     {1, 1, 1, 2}, {1, 2, 2, 2}, {1, 2, 2, 4}, {1, 2, 4, 2}, {1, 4, 4, 4},
1494   };
1495   for (int iPatternIdx = 0; iPatternIdx < PATTERN_NUM; iPatternIdx++) {
1496     for (int i = 0; i < iSpatialLayerNum; i++) {
1497       param_.sSpatialLayers[i].fFrameRate = (fFrameRate / iTemporalPattern[iPatternIdx][i]);
1498     }
1499 
1500     int rv = encoder_->InitializeExt (&param_);
1501     ASSERT_TRUE (rv == cmResultSuccess);
1502 
1503     iEncFrameNum = 10;
1504     int iInsertIdr = rand() % iEncFrameNum;
1505     for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
1506       int iResult;
1507       int iLayerLen = 0;
1508       unsigned char* pData[3] = { NULL };
1509 
1510       ASSERT_TRUE (InitialEncDec (param_.iPicWidth, param_.iPicHeight));
1511       EncodeOneFrame (0);
1512 
1513       if (iInsertIdr == iFrame) {
1514         encoder_->ForceIntraFrame (true);
1515       }
1516 
1517       // init aLen for the current frame
1518       for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1519         aLen[iIdx] = 0;
1520       }
1521       for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
1522         iLayerLen = 0;
1523         const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
1524         const int kiFirstNalType = ((* (layerInfo.pBsBuf + 4)) & 0x1f);
1525         ASSERT_TRUE ((kiFirstNalType == NAL_SPS) || (kiFirstNalType == NAL_PPS) || (kiFirstNalType == NAL_SLICE)
1526                      || (kiFirstNalType == NAL_SLICE_IDR) || (kiFirstNalType == NAL_SEI));
1527         for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
1528           iLayerLen += layerInfo.pNalLengthInByte[iNal];
1529         }
1530 
1531         iIdx = layerInfo.uiSpatialId;
1532         EXPECT_TRUE (iIdx < iSpatialLayerNum);
1533         memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
1534         aLen[iIdx] += iLayerLen;
1535       }
1536 
1537       for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1538         pData[0] = pData[1] = pData[2] = 0;
1539         memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
1540 
1541         if (aLen[iIdx] > 0) {
1542 #ifdef DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1543           fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
1544 #endif
1545           iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
1546           EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
1547 
1548           iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
1549           EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx << iPatternIdx;
1550           EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
1551         }
1552       }
1553     }
1554   }
1555 
1556   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1557     free (pBsBuf[iIdx]);
1558 
1559     if (decoder[iIdx] != NULL) {
1560       decoder[iIdx]->Uninitialize();
1561       WelsDestroyDecoder (decoder[iIdx]);
1562     }
1563   }
1564 #ifdef DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1565   for (int i = 0; i < MAX_SPATIAL_LAYER_NUM; i++) {
1566     fclose (fEnc[i]);
1567   }
1568 #endif
1569 }
1570 
TEST_F(EncodeDecodeTestAPI,DiffSlicingInDlayer)1571 TEST_F (EncodeDecodeTestAPI, DiffSlicingInDlayer) {
1572   int iSpatialLayerNum = 3;
1573   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, (64 << 2), MAX_WIDTH);
1574   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, (64 << 2),
1575                                 2240);//TODO: use MAX_HEIGHT after the limit is removed
1576   float fFrameRate = rand() + 0.5f;
1577   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1578 
1579   // prepare params
1580   SEncParamExt   sParam;
1581   encoder_->GetDefaultParams (&sParam);
1582   prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1583   sParam.iMultipleThreadIdc = (rand() % 4) + 1;
1584   sParam.bSimulcastAVC = 1;
1585   sParam.sSpatialLayers[0].iVideoWidth = (iWidth >> 2);
1586   sParam.sSpatialLayers[0].iVideoHeight = (iHeight >> 2);
1587   sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = SM_RASTER_SLICE;
1588   sParam.sSpatialLayers[1].sSliceArgument.uiSliceMbNum[0] = 0;
1589 
1590   sParam.sSpatialLayers[1].iVideoWidth = (iWidth >> 1);
1591   sParam.sSpatialLayers[1].iVideoHeight = (iHeight >> 1);
1592   sParam.sSpatialLayers[1].sSliceArgument.uiSliceMode = SM_RASTER_SLICE;
1593   sParam.sSpatialLayers[1].sSliceArgument.uiSliceMbNum[0] = 30;
1594   sParam.sSpatialLayers[1].sSliceArgument.uiSliceMbNum[1] = 32;
1595 
1596   sParam.sSpatialLayers[2].iVideoWidth = iWidth;
1597   sParam.sSpatialLayers[2].iVideoHeight = iHeight;
1598   sParam.sSpatialLayers[2].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
1599   sParam.sSpatialLayers[2].sSliceArgument.uiSliceNum = (rand() % 30) + 1;
1600 
1601 
1602   int rv = encoder_->InitializeExt (&sParam);
1603   ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1604 
1605   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1606   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1607 
1608   int iIdx = 0;
1609 
1610   //create decoder
1611   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1612     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1613     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1614 
1615     long rv = WelsCreateDecoder (&decoder[iIdx]);
1616     ASSERT_EQ (0, rv);
1617     ASSERT_TRUE (decoder[iIdx] != NULL);
1618 
1619     SDecodingParam decParam;
1620     memset (&decParam, 0, sizeof (SDecodingParam));
1621     decParam.uiTargetDqLayer = UCHAR_MAX;
1622     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1623     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1624 
1625     rv = decoder[iIdx]->Initialize (&decParam);
1626     ASSERT_EQ (0, rv);
1627   }
1628 
1629   ASSERT_TRUE (TestOneSimulcastAVC (&sParam, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0));
1630 
1631   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1632     if (pBsBuf[iIdx]) {
1633       free (pBsBuf[iIdx]);
1634       pBsBuf[iIdx] = NULL;
1635     }
1636 
1637     if (decoder[iIdx] != NULL) {
1638       decoder[iIdx]->Uninitialize();
1639       WelsDestroyDecoder (decoder[iIdx]);
1640     }
1641 
1642   }
1643 }
1644 
TEST_F(EncodeDecodeTestAPI,DiffSlicingInDlayerMixed)1645 TEST_F (EncodeDecodeTestAPI, DiffSlicingInDlayerMixed) {
1646   int iSpatialLayerNum = 2;
1647   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, (64 << 2), MAX_WIDTH);
1648   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, (64 << 2),
1649                                 1120);//TODO: use MAX_HEIGHT after the limit is removed
1650   float fFrameRate = rand() + 0.5f;
1651   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1652 
1653   // prepare params
1654   SEncParamExt   sParam;
1655   encoder_->GetDefaultParams (&sParam);
1656   prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1657   sParam.iMultipleThreadIdc = (rand() % 2) ? 4 : ((rand() % 4) + 1);
1658   sParam.bSimulcastAVC = 1;
1659   sParam.sSpatialLayers[0].iVideoWidth = (iWidth >> 2);
1660   sParam.sSpatialLayers[0].iVideoHeight = (iHeight >> 2);
1661   sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = (rand() % 2) ? SM_SIZELIMITED_SLICE : SM_FIXEDSLCNUM_SLICE;
1662   sParam.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = 1500;
1663 
1664   sParam.sSpatialLayers[1].iVideoWidth = iWidth;
1665   sParam.sSpatialLayers[1].iVideoHeight = iHeight;
1666   sParam.sSpatialLayers[1].sSliceArgument.uiSliceMode = (rand() % 2) ? SM_SIZELIMITED_SLICE : SM_FIXEDSLCNUM_SLICE;
1667   sParam.sSpatialLayers[1].sSliceArgument.uiSliceNum = 1;
1668   sParam.sSpatialLayers[1].sSliceArgument.uiSliceSizeConstraint = 1500;
1669 
1670   int iTraceLevel = WELS_LOG_QUIET;
1671   int rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1672 
1673   rv = encoder_->InitializeExt (&sParam);
1674   ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1675 
1676   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1677   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1678 
1679   int iIdx = 0;
1680 
1681   //create decoder
1682   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1683     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1684     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1685 
1686     long rv = WelsCreateDecoder (&decoder[iIdx]);
1687     ASSERT_EQ (0, rv);
1688     ASSERT_TRUE (decoder[iIdx] != NULL);
1689 
1690     SDecodingParam decParam;
1691     memset (&decParam, 0, sizeof (SDecodingParam));
1692     decParam.uiTargetDqLayer = UCHAR_MAX;
1693     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1694     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1695 
1696     rv = decoder[iIdx]->Initialize (&decParam);
1697     ASSERT_EQ (0, rv);
1698   }
1699 
1700   ASSERT_TRUE (TestOneSimulcastAVC (&sParam, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0));
1701 
1702   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1703     if (pBsBuf[iIdx])
1704       free (pBsBuf[iIdx]);
1705 
1706     if (decoder[iIdx] != NULL) {
1707       decoder[iIdx]->Uninitialize();
1708       WelsDestroyDecoder (decoder[iIdx]);
1709     }
1710 
1711   }
1712 }
1713 
TEST_F(EncodeDecodeTestAPI,ThreadNumAndSliceNum)1714 TEST_F (EncodeDecodeTestAPI, ThreadNumAndSliceNum) {
1715   int iSpatialLayerNum = 1;
1716   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, (64 << 2), MAX_WIDTH);
1717   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, (64 << 2),
1718                                 2240);//TODO: use MAX_HEIGHT after the limit is removed
1719   float fFrameRate = rand() + 0.5f;
1720   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1721 
1722   // prepare params
1723   SEncParamExt   sParam;
1724   encoder_->GetDefaultParams (&sParam);
1725   prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1726   sParam.iMultipleThreadIdc = (rand() % 3) + 2;
1727   sParam.bSimulcastAVC = 1;
1728   sParam.sSpatialLayers[0].iVideoWidth = iWidth;
1729   sParam.sSpatialLayers[0].iVideoHeight = iHeight;
1730   sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
1731   sParam.sSpatialLayers[0].sSliceArgument.uiSliceNum = (rand() % 2) ? (sParam.iMultipleThreadIdc + 1) :
1732       (sParam.iMultipleThreadIdc - 1);
1733 
1734   int rv = encoder_->InitializeExt (&sParam);
1735   ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1736 
1737   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1738   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1739 
1740   int iIdx = 0;
1741 
1742   //create decoder
1743   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1744     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1745     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1746 
1747     long rv = WelsCreateDecoder (&decoder[iIdx]);
1748     ASSERT_EQ (0, rv);
1749     ASSERT_TRUE (decoder[iIdx] != NULL);
1750 
1751     SDecodingParam decParam;
1752     memset (&decParam, 0, sizeof (SDecodingParam));
1753     decParam.uiTargetDqLayer = UCHAR_MAX;
1754     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1755     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1756 
1757     rv = decoder[iIdx]->Initialize (&decParam);
1758     ASSERT_EQ (0, rv);
1759   }
1760 
1761   ASSERT_TRUE (TestOneSimulcastAVC (&sParam, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0));
1762 
1763   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1764     free (pBsBuf[iIdx]);
1765 
1766     if (decoder[iIdx] != NULL) {
1767       decoder[iIdx]->Uninitialize();
1768       WelsDestroyDecoder (decoder[iIdx]);
1769     }
1770 
1771   }
1772 }
1773 
1774 
TEST_F(EncodeDecodeTestAPI,TriggerLoadBalancing)1775 TEST_F (EncodeDecodeTestAPI, TriggerLoadBalancing) {
1776   int iSpatialLayerNum = 1;
1777   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, (64 << 2), MAX_WIDTH);
1778   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, (64 << 2),
1779                                 2240);//TODO: use MAX_HEIGHT after the limit is removed
1780   float fFrameRate = rand() + 0.5f;
1781   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1782 
1783   // prepare params
1784   SEncParamExt   sParam;
1785   encoder_->GetDefaultParams (&sParam);
1786   prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1787   sParam.iMultipleThreadIdc = 4;
1788   sParam.bSimulcastAVC = 1;
1789   sParam.sSpatialLayers[0].iVideoWidth = iWidth;
1790   sParam.sSpatialLayers[0].iVideoHeight = iHeight;
1791   sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
1792   //TODO: use this after the buffer problem is fixed. sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = (rand()%2) ? SM_FIXEDSLCNUM_SLICE : SM_SIZELIMITED_SLICE;
1793   sParam.sSpatialLayers[0].sSliceArgument.uiSliceNum = sParam.iMultipleThreadIdc;
1794   sParam.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = 1000;
1795 
1796   int iTraceLevel = WELS_LOG_QUIET;
1797   int rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1798   rv = encoder_->InitializeExt (&sParam);
1799   ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1800 
1801   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1802   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1803 
1804   int iIdx = 0;
1805   int aLen[MAX_SPATIAL_LAYER_NUM] = {};
1806 
1807   //create decoder
1808   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1809     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1810     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1811 
1812     long rv = WelsCreateDecoder (&decoder[iIdx]);
1813     ASSERT_EQ (0, rv);
1814     ASSERT_TRUE (decoder[iIdx] != NULL);
1815 
1816     SDecodingParam decParam;
1817     memset (&decParam, 0, sizeof (SDecodingParam));
1818     decParam.uiTargetDqLayer = UCHAR_MAX;
1819     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1820     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1821 
1822     rv = decoder[iIdx]->Initialize (&decParam);
1823     ASSERT_EQ (0, rv);
1824   }
1825 
1826   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam);
1827   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed pParam: rv = " << rv;
1828 
1829   //begin testing
1830   for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
1831     int iResult;
1832     int iLayerLen = 0;
1833     unsigned char* pData[3] = { NULL };
1834 
1835     ASSERT_TRUE (InitialEncDec (sParam.iPicWidth, sParam.iPicHeight));
1836     int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
1837     memset (buf_.data(), rand() % 256, (frameSize >> 2));
1838     memset (buf_.data() + (frameSize >> 2), rand() % 256, (frameSize - (frameSize >> 2)));
1839 
1840     int iStartStrip = 0;
1841     //during first half the complex strip is at top, then during the second half it is at bottom
1842     if (iFrame > iEncFrameNum / 2) {
1843       iStartStrip = EncPic.iPicHeight * EncPic.iPicWidth;
1844     }
1845     for (int k = 0; k < (EncPic.iPicHeight / 2); k++) {
1846       memset (buf_.data() + k * EncPic.iPicWidth + iStartStrip, rand() % 256, (EncPic.iPicWidth));
1847     }
1848 
1849     int rv = encoder_->EncodeFrame (&EncPic, &info);
1850     ASSERT_TRUE (rv == cmResultSuccess);
1851 
1852     // init
1853     for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1854       aLen[iIdx] = 0;
1855     }
1856     for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
1857       iLayerLen = 0;
1858       const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
1859       for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
1860         iLayerLen += layerInfo.pNalLengthInByte[iNal];
1861       }
1862 
1863       iIdx = layerInfo.uiSpatialId;
1864       EXPECT_TRUE (iIdx < iSpatialLayerNum) << "iIdx = " << iIdx << ", iSpatialLayerNum = " << iSpatialLayerNum;
1865       memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
1866       aLen[iIdx] += iLayerLen;
1867     }
1868 
1869     for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1870       pData[0] = pData[1] = pData[2] = 0;
1871       memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
1872 
1873 #ifdef DEBUG_FILE_SAVE4
1874       fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
1875 #endif
1876       iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
1877       EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << ", LayerIdx=" << iIdx;
1878 
1879       iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
1880       EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << ", LayerIdx=" << iIdx;
1881       EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
1882     }
1883   }
1884 
1885   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1886     free (pBsBuf[iIdx]);
1887 
1888     if (decoder[iIdx] != NULL) {
1889       decoder[iIdx]->Uninitialize();
1890       WelsDestroyDecoder (decoder[iIdx]);
1891     }
1892 
1893   }
1894 }
1895 
CheckLevelLimitation(SEncParamExt * pParam)1896 ELevelIdc CheckLevelLimitation (SEncParamExt*  pParam) {
1897   int32_t iOrder = 0;
1898   ELevelIdc iLevel = LEVEL_5_2;
1899   const SLevelLimits* kpLevelLimit = g_ksLevelLimits;
1900   uint32_t uiPicWidthInMBs = (pParam->sSpatialLayers[0].iVideoWidth + 15) >> 4;
1901   uint32_t uiPicHeightInMBs = (pParam->sSpatialLayers[0].iVideoHeight + 15) >> 4;
1902   uint32_t uiPicInMBs = uiPicWidthInMBs * uiPicHeightInMBs;
1903   uint32_t uiNumRefFrames = pParam->iNumRefFrame;
1904   for (iOrder = 0; iOrder < LEVEL_NUMBER; iOrder++, kpLevelLimit++) {
1905 
1906 
1907     if (kpLevelLimit->uiMaxMBPS < (uint32_t) (uiPicInMBs * pParam->fMaxFrameRate))
1908       continue;
1909 
1910     if (kpLevelLimit->uiMaxFS < uiPicInMBs)
1911       continue;
1912 
1913     if ((kpLevelLimit->uiMaxFS << 3) < (uiPicWidthInMBs * uiPicWidthInMBs))
1914       continue;
1915     if ((kpLevelLimit->uiMaxFS << 3) < (uiPicHeightInMBs * uiPicHeightInMBs))
1916       continue;
1917     if (kpLevelLimit->uiMaxDPBMbs < uiNumRefFrames * uiPicInMBs)
1918       continue;
1919 
1920     if ((pParam->sSpatialLayers[0].iSpatialBitrate != UNSPECIFIED_BIT_RATE)
1921         && ((int32_t) kpLevelLimit->uiMaxBR  * 1200) <
1922         pParam->sSpatialLayers[0].iSpatialBitrate)   //RC enabled, considering bitrate constraint
1923       continue;
1924 
1925     break;
1926   }
1927   iLevel = kpLevelLimit->uiLevelIdc;
1928 
1929   return iLevel;
1930 }
TEST_F(EncodeDecodeTestAPI,ProfileLevelSetting)1931 TEST_F (EncodeDecodeTestAPI, ProfileLevelSetting) {
1932   int iWidth       = GetRandWidth();
1933   int iHeight      = GetRandHeight();
1934   float fFrameRate = rand() % 30 + 0.5f;
1935   int iEncFrameNum = 0;
1936   int iSpatialLayerNum = 1;
1937   int iSliceNum        = 1;
1938 
1939   EProfileIdc profileList[11] = {PRO_UNKNOWN, PRO_BASELINE, PRO_MAIN,
1940                                  PRO_EXTENDED, PRO_HIGH, PRO_HIGH10,
1941                                  PRO_HIGH422, PRO_HIGH444, PRO_CAVLC444,
1942                                  PRO_SCALABLE_BASELINE,
1943                                  PRO_SCALABLE_HIGH
1944                                 };
1945   ELevelIdc levelList[18] = {  LEVEL_UNKNOWN, LEVEL_1_0, LEVEL_1_B, LEVEL_1_1, LEVEL_1_2,
1946                                LEVEL_1_3, LEVEL_2_0, LEVEL_2_1, LEVEL_2_2, LEVEL_3_0,
1947                                LEVEL_3_1, LEVEL_3_2, LEVEL_4_0, LEVEL_4_1,
1948                                LEVEL_4_2, LEVEL_5_0, LEVEL_5_1, LEVEL_5_2
1949                             };
1950 
1951   EProfileIdc iEncProfileIdc = PRO_UNKNOWN;
1952   ELevelIdc iEncLevelIdc =  LEVEL_UNKNOWN;
1953 
1954   EProfileIdc iDecProfileIdc = PRO_UNKNOWN;
1955   ELevelIdc iDecLevelIdc =  LEVEL_UNKNOWN;
1956 
1957   // prepare params
1958   SEncParamExt   sParam;
1959   encoder_->GetDefaultParams (&sParam);
1960   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
1961   sParam.bSimulcastAVC = 1;
1962   sParam.iRCMode = RC_TIMESTAMP_MODE;
1963   sParam.iNumRefFrame = 1;
1964   sParam.fMaxFrameRate = fFrameRate;
1965   sParam.iEntropyCodingModeFlag = rand() % 2;
1966   sParam.sSpatialLayers[0].iSpatialBitrate = sParam.iTargetBitrate = 3000;
1967 
1968 //  int TraceLevel = WELS_LOG_DEBUG;
1969 //  encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
1970   //decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &TraceLevel);
1971   iEncProfileIdc = profileList[rand() % 11];
1972   iEncLevelIdc =  levelList[rand() % 18];
1973   sParam.sSpatialLayers[0].uiProfileIdc = iEncProfileIdc;
1974   sParam.sSpatialLayers[0].uiLevelIdc = iEncLevelIdc;
1975   int rv = encoder_->InitializeExt (&sParam);
1976   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam.iPicWidth << "x" <<
1977                                       sParam.iPicHeight;
1978   ASSERT_TRUE (EncDecOneFrame (sParam.iPicWidth, sParam.iPicHeight, iEncFrameNum++, NULL));
1979 
1980   decoder_->GetOption (DECODER_OPTION_PROFILE, &iDecProfileIdc);
1981 
1982   if ((iEncProfileIdc != PRO_BASELINE) && (iEncProfileIdc != PRO_MAIN) && (iEncProfileIdc != PRO_HIGH)) {
1983     if (sParam.iEntropyCodingModeFlag) {
1984       iEncProfileIdc = PRO_HIGH;
1985     } else {
1986       iEncProfileIdc = PRO_BASELINE;
1987     }
1988   }
1989 
1990   ASSERT_TRUE (iDecProfileIdc == iEncProfileIdc) << "enc_profile = " << iEncProfileIdc << "  dec_profile = " <<
1991       iDecProfileIdc;
1992 
1993   //check whether the level is changed according to level limitation
1994   ELevelIdc uiLevel = LEVEL_UNKNOWN;
1995   if (iEncLevelIdc != LEVEL_UNKNOWN) {
1996     uiLevel = CheckLevelLimitation (&sParam) ;
1997     if ((uiLevel == LEVEL_1_B) &&
1998         ((iDecProfileIdc == PRO_BASELINE) || (iDecProfileIdc == PRO_MAIN) || (iDecProfileIdc == PRO_EXTENDED))) {
1999       uiLevel = LEVEL_1_1;
2000     }
2001     if (iEncLevelIdc < uiLevel) {
2002       iEncLevelIdc = uiLevel;
2003     }
2004   }
2005   decoder_->GetOption (DECODER_OPTION_LEVEL, &iDecLevelIdc);
2006 
2007   if (iEncLevelIdc == LEVEL_UNKNOWN)
2008     ASSERT_TRUE (iDecLevelIdc != LEVEL_UNKNOWN) << "enc_level = " << iEncLevelIdc << "  dec_level = " << iDecLevelIdc;
2009   else
2010     ASSERT_TRUE (iDecLevelIdc == iEncLevelIdc) << "enc_level = " << iEncLevelIdc << "  dec_level = " << iDecLevelIdc;
2011 
2012   rv = encoder_->Uninitialize();
2013   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2014 
2015   // new change profile
2016   iEncProfileIdc = profileList[rand() % 10];
2017   iEncLevelIdc =  levelList[rand() % 17];
2018   sParam.sSpatialLayers[0].uiProfileIdc = iEncProfileIdc;
2019   sParam.sSpatialLayers[0].uiLevelIdc = iEncLevelIdc;
2020 
2021   SProfileInfo sProfileInfo;
2022   sProfileInfo.iLayer = 0;
2023   sProfileInfo.uiProfileIdc = iEncProfileIdc;
2024 
2025   rv = encoder_->InitializeExt (&sParam);
2026   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam.iPicWidth << "x" <<
2027                                       sParam.iPicHeight;
2028 
2029   rv = encoder_->SetOption (ENCODER_OPTION_PROFILE, &sProfileInfo);
2030   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2031 
2032   SLevelInfo sLevelInfo;
2033   sLevelInfo.iLayer = 0;
2034   sLevelInfo.uiLevelIdc = iEncLevelIdc;
2035 
2036   rv = encoder_->SetOption (ENCODER_OPTION_LEVEL, &sLevelInfo);
2037   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2038 
2039   rv = encoder_->ForceIntraFrame (true);
2040   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2041 
2042   ASSERT_TRUE (EncDecOneFrame (sParam.iPicWidth, sParam.iPicHeight, iEncFrameNum++, NULL));
2043 
2044   decoder_->GetOption (DECODER_OPTION_PROFILE, &iDecProfileIdc);
2045 
2046   if ((iEncProfileIdc != PRO_BASELINE) && (iEncProfileIdc != PRO_MAIN) && (iEncProfileIdc != PRO_HIGH)) {
2047     if (sParam.iEntropyCodingModeFlag) {
2048       iEncProfileIdc = PRO_HIGH;
2049     } else {
2050       iEncProfileIdc = PRO_BASELINE;
2051     }
2052   }
2053 
2054   ASSERT_TRUE (iDecProfileIdc == iEncProfileIdc) << "enc_profile = " << iEncProfileIdc << "  dec_profile = " <<
2055       iDecProfileIdc;
2056 
2057   //check whether the level is changed according to level limitation
2058   if (iEncLevelIdc != LEVEL_UNKNOWN) {
2059     uiLevel = CheckLevelLimitation (&sParam) ;
2060     if ((uiLevel == LEVEL_1_B) &&
2061         ((iDecProfileIdc == PRO_BASELINE) || (iDecProfileIdc == PRO_MAIN) || (iDecProfileIdc == PRO_EXTENDED))) {
2062       uiLevel = LEVEL_1_1;
2063     }
2064     if (iEncLevelIdc < uiLevel) {
2065       iEncLevelIdc = uiLevel;
2066     }
2067   }
2068   decoder_->GetOption (DECODER_OPTION_LEVEL, &iDecLevelIdc);
2069 
2070   if (iEncLevelIdc == LEVEL_UNKNOWN)
2071     ASSERT_TRUE (iDecLevelIdc != LEVEL_5_2) << "enc_level = " << iEncLevelIdc << "  dec_level = " << iDecLevelIdc;
2072   else
2073     ASSERT_TRUE (iDecLevelIdc == iEncLevelIdc) << "enc_level = " << iEncLevelIdc << "  dec_level = " << iDecLevelIdc;
2074 
2075   rv = encoder_->Uninitialize();
2076   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2077 }
2078 
TEST_F(EncodeDecodeTestAPI,AVCSVCExtensionCheck)2079 TEST_F (EncodeDecodeTestAPI, AVCSVCExtensionCheck) {
2080   int iWidth       = 640;
2081   int iHeight      = 360;
2082   float fFrameRate = rand() % 30 + 0.5f;
2083   int iTotalFrame  = 10; //total test enc frame num
2084   int iSliceNum    = 1;
2085 
2086   int iRet;
2087   int iSpatialLayerNumList[] = {1, 3};
2088   int iLoopNum = 5;
2089   for (int i = 0; i < iLoopNum; ++i) {
2090     // prepare params
2091     SEncParamExt sParam;
2092     encoder_->GetDefaultParams (&sParam);
2093     int iCurrSpatialLayerNum = iSpatialLayerNumList[rand() % 2];
2094     prepareParamDefault (iCurrSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
2095     sParam.bSimulcastAVC = rand() & 1; //0 or 1
2096     sParam.iRCMode = RC_TIMESTAMP_MODE;
2097     sParam.iNumRefFrame = 1;
2098     sParam.fMaxFrameRate = fFrameRate;
2099     sParam.sSpatialLayers[0].iSpatialBitrate = sParam.iTargetBitrate = 500;
2100     sParam.sSpatialLayers[1].iSpatialBitrate = sParam.iTargetBitrate = 1000;
2101     sParam.sSpatialLayers[2].iSpatialBitrate = sParam.iTargetBitrate = 2200;
2102     sParam.iTargetBitrate = 4000;
2103     //int TraceLevel = WELS_LOG_DEBUG;
2104     //encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2105     //decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &TraceLevel);
2106     iRet = encoder_->InitializeExt (&sParam);
2107     ASSERT_TRUE (iRet == cmResultSuccess) << "InitializeExt: iRet = " << iRet << " at " << sParam.iPicWidth << "x" <<
2108                                           sParam.iPicHeight;
2109     ASSERT_TRUE (InitialEncDec (iWidth, iHeight));
2110     int iLen = 0;
2111     for (int j = 0; j < iTotalFrame; ++j) {
2112       EncodeOneFrame (0);
2113       encToDecData (info, iLen);
2114       uint8_t cTypeByte;
2115       for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
2116         SLayerBSInfo* pLayerBsInfo = &info.sLayerInfo[iLayer];
2117         for (int iPacketNum = 0; iPacketNum < pLayerBsInfo->iNalCount; ++iPacketNum) {
2118           cTypeByte = (* (pLayerBsInfo->pBsBuf + 4)) & 0x1f;
2119           if (sParam.bSimulcastAVC) {
2120             EXPECT_TRUE (cTypeByte <= 8) << "simulcastAVC, spatial_id = " << pLayerBsInfo->uiSpatialId << ", typeByte = " <<
2121                                          cTypeByte;
2122           } else {
2123             if (pLayerBsInfo->uiSpatialId == 0)
2124               EXPECT_TRUE (cTypeByte <= 8 || cTypeByte == 14) << "simulcastSVC, spatial_id = 0, typeByte = " << cTypeByte;
2125             else
2126               EXPECT_TRUE (cTypeByte >= 14) << "simulcastSVC, spatial_id = " << pLayerBsInfo->uiSpatialId << ", typeByte = " <<
2127                                             cTypeByte;;
2128           }
2129         }
2130       }
2131     }
2132     iRet = encoder_->Uninitialize();
2133     ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2134   }
2135 }
2136 
TEST_F(EncodeDecodeTestAPI,UnsupportedVideoSizeInput)2137 TEST_F (EncodeDecodeTestAPI, UnsupportedVideoSizeInput) {
2138   int iWidth       = 640;
2139   int iHeight      = 360;
2140   float fFrameRate = rand() % 30 + 0.5f;
2141   int iSliceNum    = 1;
2142   int iRet;
2143 
2144   int iSrcWidth = rand() % 15 + 1;
2145   int iSrcHeight = rand() % 15 + 1;
2146 
2147   SEncParamExt sParam;
2148   encoder_->GetDefaultParams (&sParam);
2149   prepareParamDefault (1, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
2150   sParam.bSimulcastAVC = rand() & 1; //0 or 1
2151   sParam.iRCMode = RC_OFF_MODE;
2152   sParam.iNumRefFrame = 1;
2153   sParam.fMaxFrameRate = fFrameRate;
2154   iRet = encoder_->InitializeExt (&sParam);
2155   ASSERT_TRUE (iRet == cmResultSuccess) << "InitializeExt: iRet = " << iRet << " at " << sParam.iPicWidth << "x" <<
2156                                         sParam.iPicHeight;
2157 
2158 //   int TraceLevel = WELS_LOG_DEBUG;
2159 //   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2160   ASSERT_TRUE (InitialEncDec (iSrcWidth, iSrcHeight));
2161 
2162   iRet = encoder_->EncodeFrame (&EncPic, &info);
2163   ASSERT_TRUE (iRet == cmUnsupportedData) << "rv = " << iRet;
2164 
2165   iSrcWidth = iWidth;
2166   iSrcHeight = iHeight;
2167 
2168   ASSERT_TRUE (InitialEncDec (iSrcWidth, iSrcHeight));
2169 
2170   iRet = encoder_->EncodeFrame (&EncPic, &info);
2171 
2172   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2173 
2174   iRet = encoder_->Uninitialize();
2175   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2176 
2177 }
2178 
TEST_F(EncodeDecodeTestAPI,ScreenContent_LosslessLink0_EnableLongTermReference)2179 TEST_F (EncodeDecodeTestAPI,  ScreenContent_LosslessLink0_EnableLongTermReference) {
2180   int iWidth       = 2882;
2181   int iHeight      = 1808;
2182   float fFrameRate = rand() % 30 + 0.5f;
2183   int iSliceNum    = 1;
2184   int iRet;
2185 
2186   SEncParamExt sParam;
2187   encoder_->GetDefaultParams (&sParam);
2188   prepareParamDefault (1, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
2189   sParam.iUsageType = SCREEN_CONTENT_REAL_TIME;
2190   sParam.bEnableLongTermReference = 1;
2191   sParam.bIsLosslessLink = 0;
2192   //int TraceLevel = WELS_LOG_INFO;
2193   //encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2194   iRet = encoder_->InitializeExt (&sParam);
2195   ASSERT_TRUE (iRet == cmResultSuccess) << "InitializeExt: iRet = " << iRet << " at " << sParam.iPicWidth << "x" <<
2196                                         sParam.iPicHeight;
2197 
2198 
2199   ASSERT_TRUE (InitialEncDec (iWidth, iHeight));
2200 
2201   iRet = encoder_->EncodeFrame (&EncPic, &info);
2202 
2203   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2204 
2205   iRet = encoder_->Uninitialize();
2206   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2207 
2208 }
2209 
2210 
TEST_F(EncodeDecodeTestAPI,TemporalLayerChangeDuringEncoding)2211 TEST_F (EncodeDecodeTestAPI,  TemporalLayerChangeDuringEncoding) {
2212   int iWidth       = 320;
2213   int iHeight      = 192;
2214   float fFrameRate = 15;
2215   int iSliceNum    = 1;
2216   int iRet = 0;
2217   int iTotalFrame  = 20; //total test enc frame num
2218   int iFrameNum = 0;
2219   SEncParamExt sParam;
2220   encoder_->GetDefaultParams (&sParam);
2221   prepareParamDefault (1, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
2222   sParam.iTemporalLayerNum = 2;
2223 
2224 //  int TraceLevel = WELS_LOG_DEBUG;
2225 //  encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2226   iRet = encoder_->InitializeExt (&sParam);
2227   ASSERT_TRUE (iRet == cmResultSuccess) << "InitializeExt: iRet = " << iRet << " at " << sParam.iPicWidth << "x" <<
2228                                         sParam.iPicHeight;
2229 
2230   ASSERT_TRUE (InitialEncDec (iWidth, iHeight));
2231 
2232   int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
2233   do {
2234     FileInputStream fileStream;
2235     ASSERT_TRUE (fileStream.Open ("res/CiscoVT2people_320x192_12fps.yuv"));
2236 
2237     while (fileStream.read (buf_.data(), frameSize) == frameSize) {
2238       iRet = encoder_->EncodeFrame (&EncPic, &info);
2239       ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2240       if (iFrameNum == 5) {
2241         sParam.iTemporalLayerNum = 3;
2242         sParam.iTargetBitrate = 1500000;
2243         sParam.sSpatialLayers[0].iSpatialBitrate = 1500000;
2244         sParam.fMaxFrameRate = 30;
2245         //sSvcParam.sSpatialLayers[0].fFrameRate = 30;
2246         encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam);
2247       } else if (iFrameNum == 10) {
2248         sParam.iTemporalLayerNum = 1;
2249         sParam.iTargetBitrate = 500000;
2250         sParam.sSpatialLayers[0].iSpatialBitrate = 500000;
2251         sParam.fMaxFrameRate = 7.5;
2252         //sSvcParam.sSpatialLayers[0].fFrameRate = 7.5;
2253         encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam);
2254       } else if (iFrameNum == 15) {
2255         sParam.iTemporalLayerNum = 2;
2256         sParam.iTargetBitrate = 1000000;
2257         sParam.sSpatialLayers[0].iSpatialBitrate = 1000000;
2258         sParam.fMaxFrameRate = 15;
2259         //sSvcParam.sSpatialLayers[0].fFrameRate = 15;
2260         encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam);
2261       }
2262 
2263 
2264     }
2265     iFrameNum++;
2266   } while (iFrameNum < iTotalFrame);
2267 
2268   iRet = encoder_->Uninitialize();
2269   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2270 
2271 }
2272 
TEST_F(EncodeDecodeTestAPI,TemporalLayerChangeDuringEncoding_Specific)2273 TEST_F (EncodeDecodeTestAPI,  TemporalLayerChangeDuringEncoding_Specific) {
2274   int iWidth       = 320;
2275   int iHeight      = 192;
2276   float fFrameRate = 15;
2277   int iSliceNum    = 1;
2278   int iRet = 0;
2279   int iTotalFrame  = (rand() % 20) + 3;
2280   int iFrameNum = 0;
2281   SEncParamExt sParam;
2282   encoder_->GetDefaultParams (&sParam);
2283   prepareParamDefault (1, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
2284 
2285   int originalTemporalLayerNum = 1;
2286   int originalBR = 500000;
2287   float originalFR = 7.5;
2288   int iSteps[3] = {2, 1, 3};
2289   int iStepIdx = 0;
2290   bool bSetOption = false;
2291 
2292   sParam.iTemporalLayerNum = originalTemporalLayerNum;
2293   sParam.iNumRefFrame = 1;
2294 
2295 // int TraceLevel = WELS_LOG_INFO;
2296 //  encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2297   iRet = encoder_->InitializeExt (&sParam);
2298   ASSERT_TRUE (iRet == cmResultSuccess) << "InitializeExt: iRet = " << iRet << " at " << sParam.iPicWidth << "x" <<
2299                                         sParam.iPicHeight;
2300 
2301   ASSERT_TRUE (InitialEncDec (iWidth, iHeight));
2302 
2303   int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
2304   do {
2305     FileInputStream fileStream;
2306     ASSERT_TRUE (fileStream.Open ("res/CiscoVT2people_320x192_12fps.yuv"));
2307 
2308     while (fileStream.read (buf_.data(), frameSize) == frameSize) {
2309 
2310       if ((iStepIdx < 3) && (iFrameNum == ((iTotalFrame / 3) * (iStepIdx + 1)))) {
2311         sParam.iTemporalLayerNum = originalTemporalLayerNum * iSteps[iStepIdx];
2312         sParam.iTargetBitrate = sParam.sSpatialLayers[0].iSpatialBitrate = originalBR * iSteps[iStepIdx];
2313         sParam.fMaxFrameRate = sParam.sSpatialLayers[0].fFrameRate = static_cast <float> (originalFR * pow (2.0f,
2314                                iSteps[iStepIdx]));
2315         encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam);
2316 
2317         bSetOption = true;
2318         iStepIdx += 1;
2319       }
2320 
2321       iRet = encoder_->EncodeFrame (&EncPic, &info);
2322       EXPECT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2323 
2324       if (bSetOption) {
2325         if ((iStepIdx == 1) || (iStepIdx == 3)) {
2326           EXPECT_TRUE (info.eFrameType == videoFrameTypeIDR) << "iStepIdx=" << iStepIdx << "iFrameNum=" << iFrameNum <<
2327               "iTotalFrame=" << iTotalFrame;
2328         } else {
2329           EXPECT_TRUE (info.eFrameType != videoFrameTypeIDR) << "iStepIdx=" << iStepIdx << "iFrameNum=" << iFrameNum <<
2330               "iTotalFrame=" << iTotalFrame;
2331         }
2332 
2333         bSetOption = false;
2334       }
2335 
2336 
2337     }
2338     iFrameNum++;
2339   } while (iFrameNum < iTotalFrame);
2340 
2341   iRet = encoder_->Uninitialize();
2342   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2343 
2344 }
2345 
TEST_F(EncodeDecodeTestAPI,ENCODER_OPTION_IDR_INTERVAL)2346 TEST_F (EncodeDecodeTestAPI, ENCODER_OPTION_IDR_INTERVAL) {
2347   int iSpatialLayerNum = 1;
2348   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
2349   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
2350   float fFrameRate = rand() + 0.5f;
2351   int iSliceNum        = 1;
2352   encoder_->GetDefaultParams (&param_);
2353   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
2354   param_.iTemporalLayerNum = 1;
2355 
2356   int iTraceLevel = WELS_LOG_QUIET;
2357   int rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
2358   EXPECT_TRUE (rv == cmResultSuccess);
2359 
2360   rv = encoder_->InitializeExt (&param_);
2361   ASSERT_TRUE (rv == cmResultSuccess);
2362 
2363   InitialEncDec (param_.iPicWidth, param_.iPicHeight);
2364   EncodeOneFrame (0);
2365   EXPECT_TRUE (info.eFrameType == videoFrameTypeIDR);
2366 
2367   int iLastIdrIdx = 0;
2368   int iFrame = 1;
2369   int iTtlAttempt = (rand() % 5) + 2;
2370   for (int iAtt = 0; iAtt < iTtlAttempt; iAtt++) {
2371     int kiTargetIntraPeriod = WelsClip3 ((rand() % ENCODE_FRAME_NUM) - 1, -1, ENCODE_FRAME_NUM);
2372     rv = encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &kiTargetIntraPeriod);
2373     EXPECT_TRUE (rv == cmResultSuccess);
2374 
2375     int iEncFrameNum = kiTargetIntraPeriod * 3;
2376     for (int i = 0; i < iEncFrameNum; i++) {
2377       EncodeOneFrame (0);
2378 
2379       if ((kiTargetIntraPeriod <= 0) || (((iFrame - iLastIdrIdx) % kiTargetIntraPeriod) == 0)) {
2380         EXPECT_TRUE (info.eFrameType == videoFrameTypeIDR) << "kiTargetIntraPeriod " << kiTargetIntraPeriod <<
2381             " info.eFrameType " << info.eFrameType << " Frame " << i;
2382         iLastIdrIdx = iFrame;
2383       } else {
2384         EXPECT_FALSE (info.eFrameType == videoFrameTypeIDR);
2385       }
2386 
2387       iFrame ++;
2388     }
2389   }
2390 }
2391