• 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 INSTANTIATE_TEST_CASE_P (EncodeDecodeTestAPIBase, EncodeTestAPI,
1327                          ::testing::ValuesIn (kOptionParamArray));
1328 
TEST_P(EncodeTestAPI,SetEncOptionSize)1329 TEST_P (EncodeTestAPI, SetEncOptionSize) {
1330   EncodeOptionParam p = GetParam();
1331   memset (&param_, 0, sizeof (SEncParamExt));
1332   encoder_->GetDefaultParams (&param_);
1333   param_.uiMaxNalSize = p.uiMaxNalLen;
1334   param_.iTemporalLayerNum = (rand() % 4) + 1;
1335   param_.iSpatialLayerNum = 1;
1336   param_.iUsageType = CAMERA_VIDEO_REAL_TIME;
1337   param_.iPicWidth = p.iWidth;
1338   param_.iPicHeight = p.iHeight;
1339   param_.fMaxFrameRate = p.fFramerate;
1340   param_.iRCMode = RC_OFF_MODE; //rc off
1341   param_.iMultipleThreadIdc = p.iThreads;
1342   param_.iNumRefFrame = AUTO_REF_PIC_COUNT;
1343   param_.sSpatialLayers[0].iVideoWidth = p.iWidth;
1344   param_.sSpatialLayers[0].iVideoHeight = p.iHeight;
1345   param_.sSpatialLayers[0].fFrameRate = p.fFramerate;
1346 
1347   int iSliceModeTestNum = 1;
1348   if (SM_RESERVED == p.eSliceMode) {
1349     iSliceModeTestNum = SLICE_MODE_NUM;
1350   }
1351 
1352   for (int iSliceIdx = 0; iSliceIdx < iSliceModeTestNum; iSliceIdx++) {
1353     if (1 == iSliceModeTestNum) {
1354       param_.sSpatialLayers[0].sSliceArgument.uiSliceMode = p.eSliceMode;
1355     } else {
1356       param_.sSpatialLayers[0].sSliceArgument.uiSliceMode = static_cast<SliceModeEnum> (iSliceIdx);
1357     }
1358 
1359     FILE* pFile = NULL;
1360     if (p.sFileSave != NULL && strlen (p.sFileSave) > 0) {
1361       pFile = fopen (p.sFileSave, "wb");
1362     }
1363 
1364     if (SM_FIXEDSLCNUM_SLICE == param_.sSpatialLayers[0].sSliceArgument.uiSliceMode) {
1365       param_.sSpatialLayers[0].sSliceArgument.uiSliceNum = 8;
1366     } else if (SM_RASTER_SLICE == param_.sSpatialLayers[0].sSliceArgument.uiSliceMode) {
1367       param_.sSpatialLayers[0].sSliceArgument.uiSliceMbNum[0] =
1368         param_.sSpatialLayers[0].sSliceArgument.uiSliceMbNum[1] =
1369           param_.sSpatialLayers[0].sSliceArgument.uiSliceMbNum[2] =
1370             param_.sSpatialLayers[0].sSliceArgument.uiSliceMbNum[3] = ((p.iWidth * p.iHeight) >> 10);
1371     } else if (SM_SIZELIMITED_SLICE == param_.sSpatialLayers[0].sSliceArgument.uiSliceMode && 450 > p.uiMaxNalLen) {
1372       param_.uiMaxNalSize = 450;
1373       param_.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = 450;
1374     }
1375 
1376     int32_t iTraceLevel = WELS_LOG_QUIET;
1377     encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1378     decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1379 
1380     encoder_->Uninitialize();
1381     int rv = encoder_->InitializeExt (&param_);
1382     ASSERT_TRUE (rv == cmResultSuccess);
1383     ASSERT_TRUE (InitialEncDec (p.iWidth, p.iHeight));
1384 
1385     int32_t iSpsPpsIdAddition = 1;
1386     encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
1387     int32_t iIDRPeriod = (int32_t) pow (2.0f, (param_.iTemporalLayerNum - 1)) * ((rand() % 5) + 1);
1388     encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
1389     int iIdx = 0;
1390     int iLen;
1391     unsigned char* pData[3] = { NULL };
1392 
1393     //FIXME: remove this after the multi-thread case is correctly handled in encoder
1394     if (p.iThreads > 1 && SM_SIZELIMITED_SLICE == p.eSliceMode) {
1395       p.bAllRandom = false;
1396     }
1397 
1398     while (iIdx <= p.iNumframes) {
1399       EncodeOneFrameRandom (0, p.bAllRandom);
1400       encToDecData (info, iLen);
1401       if (pFile) {
1402         fwrite (info.sLayerInfo[0].pBsBuf, iLen, 1, pFile);
1403         fflush (pFile);
1404       }
1405       memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
1406       if (iLen && p.bTestDecoder) {
1407         rv = decoder_->DecodeFrameNoDelay (info.sLayerInfo[0].pBsBuf, iLen, pData, &dstBufInfo_);
1408         ASSERT_EQ (rv, 0);
1409         ASSERT_EQ (dstBufInfo_.iBufferStatus, 1);
1410       }
1411       int iLayer = 0;
1412       while (iLayer < info.iLayerNum) {
1413         SLayerBSInfo* pLayerBsInfo = &info.sLayerInfo[iLayer];
1414         if (pLayerBsInfo != NULL) {
1415           int iNalIdx = WELS_MAX (pLayerBsInfo->iNalCount - 2, 0); // ignore last slice under single slice mode
1416           do {
1417             if (SM_SIZELIMITED_SLICE == p.eSliceMode
1418                 && p.bTestNalSize) { // ignore the case that 2 MBs in one picture, and the multithreads case, enable them when code is ready
1419               ASSERT_GE (((int)param_.uiMaxNalSize), pLayerBsInfo->pNalLengthInByte[iNalIdx]);
1420             }
1421             -- iNalIdx;
1422           } while (iNalIdx >= 0);
1423         }
1424         ++ iLayer;
1425       }
1426       iIdx++;
1427     }
1428     if (pFile) {
1429       fclose (pFile);
1430     }
1431   }
1432 }
1433 
1434 
1435 
TEST_F(EncodeDecodeTestAPI,SimulcastAVCDiffFps)1436 TEST_F (EncodeDecodeTestAPI, SimulcastAVCDiffFps) {
1437 //#define DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1438   int iSpatialLayerNum = WelsClip3 ((rand() % MAX_SPATIAL_LAYER_NUM), 2, MAX_SPATIAL_LAYER_NUM);
1439   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
1440   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
1441   iWidth = VALID_SIZE (iWidth);
1442   iHeight = VALID_SIZE (iHeight);
1443 
1444   float fFrameRate = 30;
1445   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1446   int iSliceNum        = 1;
1447   encoder_->GetDefaultParams (&param_);
1448   prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
1449 
1450   //set flag of bSimulcastAVC
1451   param_.bSimulcastAVC = true;
1452   param_.iTemporalLayerNum = (rand() % 2) ? 3 : 4;
1453 
1454   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1455   int aLen[MAX_SPATIAL_LAYER_NUM] = {0};
1456   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1457 
1458 #ifdef DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1459   FILE* fEnc[MAX_SPATIAL_LAYER_NUM];
1460   fEnc[0] = fopen ("enc0.264", "wb");
1461   fEnc[1] = fopen ("enc1.264", "wb");
1462   fEnc[2] = fopen ("enc2.264", "wb");
1463   fEnc[3] = fopen ("enc3.264", "wb");
1464 #endif
1465 
1466   int iIdx = 0;
1467 
1468   //create decoder
1469   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1470     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1471     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1472     aLen[iIdx] = 0;
1473 
1474     long rv = WelsCreateDecoder (&decoder[iIdx]);
1475     ASSERT_EQ (0, rv);
1476     ASSERT_TRUE (decoder[iIdx] != NULL);
1477 
1478     SDecodingParam decParam;
1479     memset (&decParam, 0, sizeof (SDecodingParam));
1480     decParam.uiTargetDqLayer = UCHAR_MAX;
1481     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1482     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1483 
1484     rv = decoder[iIdx]->Initialize (&decParam);
1485     ASSERT_EQ (0, rv);
1486   }
1487 
1488 #define PATTERN_NUM (18)
1489   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},
1490     {1, 2, 1, 1}, {1, 1, 2, 1}, {1, 4, 1, 1}, {2, 4, 2, 1}, {1, 4, 2, 1}, {1, 4, 4, 1},
1491     {1, 2, 2, 1}, {2, 1, 2, 1}, {1, 2, 4, 1},
1492     {1, 1, 1, 2}, {1, 2, 2, 2}, {1, 2, 2, 4}, {1, 2, 4, 2}, {1, 4, 4, 4},
1493   };
1494   for (int iPatternIdx = 0; iPatternIdx < PATTERN_NUM; iPatternIdx++) {
1495     for (int i = 0; i < iSpatialLayerNum; i++) {
1496       param_.sSpatialLayers[i].fFrameRate = (fFrameRate / iTemporalPattern[iPatternIdx][i]);
1497     }
1498 
1499     int rv = encoder_->InitializeExt (&param_);
1500     ASSERT_TRUE (rv == cmResultSuccess);
1501 
1502     iEncFrameNum = 10;
1503     int iInsertIdr = rand() % iEncFrameNum;
1504     for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
1505       int iResult;
1506       int iLayerLen = 0;
1507       unsigned char* pData[3] = { NULL };
1508 
1509       ASSERT_TRUE (InitialEncDec (param_.iPicWidth, param_.iPicHeight));
1510       EncodeOneFrame (0);
1511 
1512       if (iInsertIdr == iFrame) {
1513         encoder_->ForceIntraFrame (true);
1514       }
1515 
1516       // init aLen for the current frame
1517       for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1518         aLen[iIdx] = 0;
1519       }
1520       for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
1521         iLayerLen = 0;
1522         const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
1523         const int kiFirstNalType = ((* (layerInfo.pBsBuf + 4)) & 0x1f);
1524         ASSERT_TRUE ((kiFirstNalType == NAL_SPS) || (kiFirstNalType == NAL_PPS) || (kiFirstNalType == NAL_SLICE)
1525                      || (kiFirstNalType == NAL_SLICE_IDR) || (kiFirstNalType == NAL_SEI));
1526         for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
1527           iLayerLen += layerInfo.pNalLengthInByte[iNal];
1528         }
1529 
1530         iIdx = layerInfo.uiSpatialId;
1531         EXPECT_TRUE (iIdx < iSpatialLayerNum);
1532         memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
1533         aLen[iIdx] += iLayerLen;
1534       }
1535 
1536       for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1537         pData[0] = pData[1] = pData[2] = 0;
1538         memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
1539 
1540         if (aLen[iIdx] > 0) {
1541 #ifdef DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1542           fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
1543 #endif
1544           iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
1545           EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
1546 
1547           iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
1548           EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx << iPatternIdx;
1549           EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
1550         }
1551       }
1552     }
1553   }
1554 
1555   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1556     free (pBsBuf[iIdx]);
1557 
1558     if (decoder[iIdx] != NULL) {
1559       decoder[iIdx]->Uninitialize();
1560       WelsDestroyDecoder (decoder[iIdx]);
1561     }
1562   }
1563 #ifdef DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1564   for (int i = 0; i < MAX_SPATIAL_LAYER_NUM; i++) {
1565     fclose (fEnc[i]);
1566   }
1567 #endif
1568 }
1569 
TEST_F(EncodeDecodeTestAPI,DiffSlicingInDlayer)1570 TEST_F (EncodeDecodeTestAPI, DiffSlicingInDlayer) {
1571   int iSpatialLayerNum = 3;
1572   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, (64 << 2), MAX_WIDTH);
1573   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, (64 << 2),
1574                                 2240);//TODO: use MAX_HEIGHT after the limit is removed
1575   float fFrameRate = rand() + 0.5f;
1576   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1577 
1578   // prepare params
1579   SEncParamExt   sParam;
1580   encoder_->GetDefaultParams (&sParam);
1581   prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1582   sParam.iMultipleThreadIdc = (rand() % 4) + 1;
1583   sParam.bSimulcastAVC = 1;
1584   sParam.sSpatialLayers[0].iVideoWidth = (iWidth >> 2);
1585   sParam.sSpatialLayers[0].iVideoHeight = (iHeight >> 2);
1586   sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = SM_RASTER_SLICE;
1587   sParam.sSpatialLayers[1].sSliceArgument.uiSliceMbNum[0] = 0;
1588 
1589   sParam.sSpatialLayers[1].iVideoWidth = (iWidth >> 1);
1590   sParam.sSpatialLayers[1].iVideoHeight = (iHeight >> 1);
1591   sParam.sSpatialLayers[1].sSliceArgument.uiSliceMode = SM_RASTER_SLICE;
1592   sParam.sSpatialLayers[1].sSliceArgument.uiSliceMbNum[0] = 30;
1593   sParam.sSpatialLayers[1].sSliceArgument.uiSliceMbNum[1] = 32;
1594 
1595   sParam.sSpatialLayers[2].iVideoWidth = iWidth;
1596   sParam.sSpatialLayers[2].iVideoHeight = iHeight;
1597   sParam.sSpatialLayers[2].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
1598   sParam.sSpatialLayers[2].sSliceArgument.uiSliceNum = (rand() % 30) + 1;
1599 
1600 
1601   int rv = encoder_->InitializeExt (&sParam);
1602   ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1603 
1604   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1605   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1606 
1607   int iIdx = 0;
1608 
1609   //create decoder
1610   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1611     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1612     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1613 
1614     long rv = WelsCreateDecoder (&decoder[iIdx]);
1615     ASSERT_EQ (0, rv);
1616     ASSERT_TRUE (decoder[iIdx] != NULL);
1617 
1618     SDecodingParam decParam;
1619     memset (&decParam, 0, sizeof (SDecodingParam));
1620     decParam.uiTargetDqLayer = UCHAR_MAX;
1621     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1622     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1623 
1624     rv = decoder[iIdx]->Initialize (&decParam);
1625     ASSERT_EQ (0, rv);
1626   }
1627 
1628   ASSERT_TRUE (TestOneSimulcastAVC (&sParam, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0));
1629 
1630   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1631     if (pBsBuf[iIdx]) {
1632       free (pBsBuf[iIdx]);
1633       pBsBuf[iIdx] = NULL;
1634     }
1635 
1636     if (decoder[iIdx] != NULL) {
1637       decoder[iIdx]->Uninitialize();
1638       WelsDestroyDecoder (decoder[iIdx]);
1639     }
1640 
1641   }
1642 }
1643 
TEST_F(EncodeDecodeTestAPI,DiffSlicingInDlayerMixed)1644 TEST_F (EncodeDecodeTestAPI, DiffSlicingInDlayerMixed) {
1645   int iSpatialLayerNum = 2;
1646   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, (64 << 2), MAX_WIDTH);
1647   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, (64 << 2),
1648                                 1120);//TODO: use MAX_HEIGHT after the limit is removed
1649   float fFrameRate = rand() + 0.5f;
1650   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1651 
1652   // prepare params
1653   SEncParamExt   sParam;
1654   encoder_->GetDefaultParams (&sParam);
1655   prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1656   sParam.iMultipleThreadIdc = (rand() % 2) ? 4 : ((rand() % 4) + 1);
1657   sParam.bSimulcastAVC = 1;
1658   sParam.sSpatialLayers[0].iVideoWidth = (iWidth >> 2);
1659   sParam.sSpatialLayers[0].iVideoHeight = (iHeight >> 2);
1660   sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = (rand() % 2) ? SM_SIZELIMITED_SLICE : SM_FIXEDSLCNUM_SLICE;
1661   sParam.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = 1500;
1662 
1663   sParam.sSpatialLayers[1].iVideoWidth = iWidth;
1664   sParam.sSpatialLayers[1].iVideoHeight = iHeight;
1665   sParam.sSpatialLayers[1].sSliceArgument.uiSliceMode = (rand() % 2) ? SM_SIZELIMITED_SLICE : SM_FIXEDSLCNUM_SLICE;
1666   sParam.sSpatialLayers[1].sSliceArgument.uiSliceNum = 1;
1667   sParam.sSpatialLayers[1].sSliceArgument.uiSliceSizeConstraint = 1500;
1668 
1669   int iTraceLevel = WELS_LOG_QUIET;
1670   int rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1671 
1672   rv = encoder_->InitializeExt (&sParam);
1673   ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1674 
1675   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1676   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1677 
1678   int iIdx = 0;
1679 
1680   //create decoder
1681   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1682     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1683     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1684 
1685     long rv = WelsCreateDecoder (&decoder[iIdx]);
1686     ASSERT_EQ (0, rv);
1687     ASSERT_TRUE (decoder[iIdx] != NULL);
1688 
1689     SDecodingParam decParam;
1690     memset (&decParam, 0, sizeof (SDecodingParam));
1691     decParam.uiTargetDqLayer = UCHAR_MAX;
1692     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1693     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1694 
1695     rv = decoder[iIdx]->Initialize (&decParam);
1696     ASSERT_EQ (0, rv);
1697   }
1698 
1699   ASSERT_TRUE (TestOneSimulcastAVC (&sParam, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0));
1700 
1701   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1702     if (pBsBuf[iIdx])
1703       free (pBsBuf[iIdx]);
1704 
1705     if (decoder[iIdx] != NULL) {
1706       decoder[iIdx]->Uninitialize();
1707       WelsDestroyDecoder (decoder[iIdx]);
1708     }
1709 
1710   }
1711 }
1712 
TEST_F(EncodeDecodeTestAPI,ThreadNumAndSliceNum)1713 TEST_F (EncodeDecodeTestAPI, ThreadNumAndSliceNum) {
1714   int iSpatialLayerNum = 1;
1715   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, (64 << 2), MAX_WIDTH);
1716   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, (64 << 2),
1717                                 2240);//TODO: use MAX_HEIGHT after the limit is removed
1718   float fFrameRate = rand() + 0.5f;
1719   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1720 
1721   // prepare params
1722   SEncParamExt   sParam;
1723   encoder_->GetDefaultParams (&sParam);
1724   prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1725   sParam.iMultipleThreadIdc = (rand() % 3) + 2;
1726   sParam.bSimulcastAVC = 1;
1727   sParam.sSpatialLayers[0].iVideoWidth = iWidth;
1728   sParam.sSpatialLayers[0].iVideoHeight = iHeight;
1729   sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
1730   sParam.sSpatialLayers[0].sSliceArgument.uiSliceNum = (rand() % 2) ? (sParam.iMultipleThreadIdc + 1) :
1731       (sParam.iMultipleThreadIdc - 1);
1732 
1733   int rv = encoder_->InitializeExt (&sParam);
1734   ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1735 
1736   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1737   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1738 
1739   int iIdx = 0;
1740 
1741   //create decoder
1742   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1743     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1744     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1745 
1746     long rv = WelsCreateDecoder (&decoder[iIdx]);
1747     ASSERT_EQ (0, rv);
1748     ASSERT_TRUE (decoder[iIdx] != NULL);
1749 
1750     SDecodingParam decParam;
1751     memset (&decParam, 0, sizeof (SDecodingParam));
1752     decParam.uiTargetDqLayer = UCHAR_MAX;
1753     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1754     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1755 
1756     rv = decoder[iIdx]->Initialize (&decParam);
1757     ASSERT_EQ (0, rv);
1758   }
1759 
1760   ASSERT_TRUE (TestOneSimulcastAVC (&sParam, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0));
1761 
1762   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1763     free (pBsBuf[iIdx]);
1764 
1765     if (decoder[iIdx] != NULL) {
1766       decoder[iIdx]->Uninitialize();
1767       WelsDestroyDecoder (decoder[iIdx]);
1768     }
1769 
1770   }
1771 }
1772 
1773 
TEST_F(EncodeDecodeTestAPI,TriggerLoadBalancing)1774 TEST_F (EncodeDecodeTestAPI, TriggerLoadBalancing) {
1775   int iSpatialLayerNum = 1;
1776   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, (64 << 2), MAX_WIDTH);
1777   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, (64 << 2),
1778                                 2240);//TODO: use MAX_HEIGHT after the limit is removed
1779   float fFrameRate = rand() + 0.5f;
1780   int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1781 
1782   // prepare params
1783   SEncParamExt   sParam;
1784   encoder_->GetDefaultParams (&sParam);
1785   prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1786   sParam.iMultipleThreadIdc = 4;
1787   sParam.bSimulcastAVC = 1;
1788   sParam.sSpatialLayers[0].iVideoWidth = iWidth;
1789   sParam.sSpatialLayers[0].iVideoHeight = iHeight;
1790   sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
1791   //TODO: use this after the buffer problem is fixed. sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = (rand()%2) ? SM_FIXEDSLCNUM_SLICE : SM_SIZELIMITED_SLICE;
1792   sParam.sSpatialLayers[0].sSliceArgument.uiSliceNum = sParam.iMultipleThreadIdc;
1793   sParam.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = 1000;
1794 
1795   int iTraceLevel = WELS_LOG_QUIET;
1796   int rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1797   rv = encoder_->InitializeExt (&sParam);
1798   ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1799 
1800   unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
1801   ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1802 
1803   int iIdx = 0;
1804   int aLen[MAX_SPATIAL_LAYER_NUM] = {};
1805 
1806   //create decoder
1807   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1808     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1809     ASSERT_TRUE (pBsBuf[iIdx] != NULL);
1810 
1811     long rv = WelsCreateDecoder (&decoder[iIdx]);
1812     ASSERT_EQ (0, rv);
1813     ASSERT_TRUE (decoder[iIdx] != NULL);
1814 
1815     SDecodingParam decParam;
1816     memset (&decParam, 0, sizeof (SDecodingParam));
1817     decParam.uiTargetDqLayer = UCHAR_MAX;
1818     decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1819     decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1820 
1821     rv = decoder[iIdx]->Initialize (&decParam);
1822     ASSERT_EQ (0, rv);
1823   }
1824 
1825   rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam);
1826   ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed pParam: rv = " << rv;
1827 
1828   //begin testing
1829   for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
1830     int iResult;
1831     int iLayerLen = 0;
1832     unsigned char* pData[3] = { NULL };
1833 
1834     ASSERT_TRUE (InitialEncDec (sParam.iPicWidth, sParam.iPicHeight));
1835     int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
1836     memset (buf_.data(), rand() % 256, (frameSize >> 2));
1837     memset (buf_.data() + (frameSize >> 2), rand() % 256, (frameSize - (frameSize >> 2)));
1838 
1839     int iStartStrip = 0;
1840     //during first half the complex strip is at top, then during the second half it is at bottom
1841     if (iFrame > iEncFrameNum / 2) {
1842       iStartStrip = EncPic.iPicHeight * EncPic.iPicWidth;
1843     }
1844     for (int k = 0; k < (EncPic.iPicHeight / 2); k++) {
1845       memset (buf_.data() + k * EncPic.iPicWidth + iStartStrip, rand() % 256, (EncPic.iPicWidth));
1846     }
1847 
1848     int rv = encoder_->EncodeFrame (&EncPic, &info);
1849     ASSERT_TRUE (rv == cmResultSuccess);
1850 
1851     // init
1852     for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1853       aLen[iIdx] = 0;
1854     }
1855     for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
1856       iLayerLen = 0;
1857       const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
1858       for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
1859         iLayerLen += layerInfo.pNalLengthInByte[iNal];
1860       }
1861 
1862       iIdx = layerInfo.uiSpatialId;
1863       EXPECT_TRUE (iIdx < iSpatialLayerNum) << "iIdx = " << iIdx << ", iSpatialLayerNum = " << iSpatialLayerNum;
1864       memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
1865       aLen[iIdx] += iLayerLen;
1866     }
1867 
1868     for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1869       pData[0] = pData[1] = pData[2] = 0;
1870       memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
1871 
1872 #ifdef DEBUG_FILE_SAVE4
1873       fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
1874 #endif
1875       iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
1876       EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << ", LayerIdx=" << iIdx;
1877 
1878       iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
1879       EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << ", LayerIdx=" << iIdx;
1880       EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
1881     }
1882   }
1883 
1884   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1885     free (pBsBuf[iIdx]);
1886 
1887     if (decoder[iIdx] != NULL) {
1888       decoder[iIdx]->Uninitialize();
1889       WelsDestroyDecoder (decoder[iIdx]);
1890     }
1891 
1892   }
1893 }
1894 
CheckLevelLimitation(SEncParamExt * pParam)1895 ELevelIdc CheckLevelLimitation (SEncParamExt*  pParam) {
1896   int32_t iOrder = 0;
1897   ELevelIdc iLevel = LEVEL_5_2;
1898   const SLevelLimits* kpLevelLimit = g_ksLevelLimits;
1899   uint32_t uiPicWidthInMBs = (pParam->sSpatialLayers[0].iVideoWidth + 15) >> 4;
1900   uint32_t uiPicHeightInMBs = (pParam->sSpatialLayers[0].iVideoHeight + 15) >> 4;
1901   uint32_t uiPicInMBs = uiPicWidthInMBs * uiPicHeightInMBs;
1902   uint32_t uiNumRefFrames = pParam->iNumRefFrame;
1903   for (iOrder = 0; iOrder < LEVEL_NUMBER; iOrder++, kpLevelLimit++) {
1904 
1905 
1906     if (kpLevelLimit->uiMaxMBPS < (uint32_t) (uiPicInMBs * pParam->fMaxFrameRate))
1907       continue;
1908 
1909     if (kpLevelLimit->uiMaxFS < uiPicInMBs)
1910       continue;
1911 
1912     if ((kpLevelLimit->uiMaxFS << 3) < (uiPicWidthInMBs * uiPicWidthInMBs))
1913       continue;
1914     if ((kpLevelLimit->uiMaxFS << 3) < (uiPicHeightInMBs * uiPicHeightInMBs))
1915       continue;
1916     if (kpLevelLimit->uiMaxDPBMbs < uiNumRefFrames * uiPicInMBs)
1917       continue;
1918 
1919     if ((pParam->sSpatialLayers[0].iSpatialBitrate != UNSPECIFIED_BIT_RATE)
1920         && ((int32_t) kpLevelLimit->uiMaxBR  * 1200) <
1921         pParam->sSpatialLayers[0].iSpatialBitrate)   //RC enabled, considering bitrate constraint
1922       continue;
1923 
1924     break;
1925   }
1926   iLevel = kpLevelLimit->uiLevelIdc;
1927 
1928   return iLevel;
1929 }
TEST_F(EncodeDecodeTestAPI,ProfileLevelSetting)1930 TEST_F (EncodeDecodeTestAPI, ProfileLevelSetting) {
1931   int iWidth       = GetRandWidth();
1932   int iHeight      = GetRandHeight();
1933   float fFrameRate = rand() % 30 + 0.5f;
1934   int iEncFrameNum = 0;
1935   int iSpatialLayerNum = 1;
1936   int iSliceNum        = 1;
1937 
1938   EProfileIdc profileList[11] = {PRO_UNKNOWN, PRO_BASELINE, PRO_MAIN,
1939                                  PRO_EXTENDED, PRO_HIGH, PRO_HIGH10,
1940                                  PRO_HIGH422, PRO_HIGH444, PRO_CAVLC444,
1941                                  PRO_SCALABLE_BASELINE,
1942                                  PRO_SCALABLE_HIGH
1943                                 };
1944   ELevelIdc levelList[18] = {  LEVEL_UNKNOWN, LEVEL_1_0, LEVEL_1_B, LEVEL_1_1, LEVEL_1_2,
1945                                LEVEL_1_3, LEVEL_2_0, LEVEL_2_1, LEVEL_2_2, LEVEL_3_0,
1946                                LEVEL_3_1, LEVEL_3_2, LEVEL_4_0, LEVEL_4_1,
1947                                LEVEL_4_2, LEVEL_5_0, LEVEL_5_1, LEVEL_5_2
1948                             };
1949 
1950   EProfileIdc iEncProfileIdc = PRO_UNKNOWN;
1951   ELevelIdc iEncLevelIdc =  LEVEL_UNKNOWN;
1952 
1953   EProfileIdc iDecProfileIdc = PRO_UNKNOWN;
1954   ELevelIdc iDecLevelIdc =  LEVEL_UNKNOWN;
1955 
1956   // prepare params
1957   SEncParamExt   sParam;
1958   encoder_->GetDefaultParams (&sParam);
1959   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
1960   sParam.bSimulcastAVC = 1;
1961   sParam.iRCMode = RC_TIMESTAMP_MODE;
1962   sParam.iNumRefFrame = 1;
1963   sParam.fMaxFrameRate = fFrameRate;
1964   sParam.iEntropyCodingModeFlag = rand() % 2;
1965   sParam.sSpatialLayers[0].iSpatialBitrate = sParam.iTargetBitrate = 3000;
1966 
1967 //  int TraceLevel = WELS_LOG_DEBUG;
1968 //  encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
1969   //decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &TraceLevel);
1970   iEncProfileIdc = profileList[rand() % 11];
1971   iEncLevelIdc =  levelList[rand() % 18];
1972   sParam.sSpatialLayers[0].uiProfileIdc = iEncProfileIdc;
1973   sParam.sSpatialLayers[0].uiLevelIdc = iEncLevelIdc;
1974   int rv = encoder_->InitializeExt (&sParam);
1975   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam.iPicWidth << "x" <<
1976                                       sParam.iPicHeight;
1977   ASSERT_TRUE (EncDecOneFrame (sParam.iPicWidth, sParam.iPicHeight, iEncFrameNum++, NULL));
1978 
1979   decoder_->GetOption (DECODER_OPTION_PROFILE, &iDecProfileIdc);
1980 
1981   if ((iEncProfileIdc != PRO_BASELINE) && (iEncProfileIdc != PRO_MAIN) && (iEncProfileIdc != PRO_HIGH)) {
1982     if (sParam.iEntropyCodingModeFlag) {
1983       iEncProfileIdc = PRO_HIGH;
1984     } else {
1985       iEncProfileIdc = PRO_BASELINE;
1986     }
1987   }
1988 
1989   ASSERT_TRUE (iDecProfileIdc == iEncProfileIdc) << "enc_profile = " << iEncProfileIdc << "  dec_profile = " <<
1990       iDecProfileIdc;
1991 
1992   //check whether the level is changed according to level limitation
1993   ELevelIdc uiLevel = LEVEL_UNKNOWN;
1994   if (iEncLevelIdc != LEVEL_UNKNOWN) {
1995     uiLevel = CheckLevelLimitation (&sParam) ;
1996     if ((uiLevel == LEVEL_1_B) &&
1997         ((iDecProfileIdc == PRO_BASELINE) || (iDecProfileIdc == PRO_MAIN) || (iDecProfileIdc == PRO_EXTENDED))) {
1998       uiLevel = LEVEL_1_1;
1999     }
2000     if (iEncLevelIdc < uiLevel) {
2001       iEncLevelIdc = uiLevel;
2002     }
2003   }
2004   decoder_->GetOption (DECODER_OPTION_LEVEL, &iDecLevelIdc);
2005 
2006   if (iEncLevelIdc == LEVEL_UNKNOWN)
2007     ASSERT_TRUE (iDecLevelIdc != LEVEL_UNKNOWN) << "enc_level = " << iEncLevelIdc << "  dec_level = " << iDecLevelIdc;
2008   else
2009     ASSERT_TRUE (iDecLevelIdc == iEncLevelIdc) << "enc_level = " << iEncLevelIdc << "  dec_level = " << iDecLevelIdc;
2010 
2011   rv = encoder_->Uninitialize();
2012   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2013 
2014   // new change profile
2015   iEncProfileIdc = profileList[rand() % 10];
2016   iEncLevelIdc =  levelList[rand() % 17];
2017   sParam.sSpatialLayers[0].uiProfileIdc = iEncProfileIdc;
2018   sParam.sSpatialLayers[0].uiLevelIdc = iEncLevelIdc;
2019 
2020   SProfileInfo sProfileInfo;
2021   sProfileInfo.iLayer = 0;
2022   sProfileInfo.uiProfileIdc = iEncProfileIdc;
2023 
2024   rv = encoder_->InitializeExt (&sParam);
2025   ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam.iPicWidth << "x" <<
2026                                       sParam.iPicHeight;
2027 
2028   rv = encoder_->SetOption (ENCODER_OPTION_PROFILE, &sProfileInfo);
2029   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2030 
2031   SLevelInfo sLevelInfo;
2032   sLevelInfo.iLayer = 0;
2033   sLevelInfo.uiLevelIdc = iEncLevelIdc;
2034 
2035   rv = encoder_->SetOption (ENCODER_OPTION_LEVEL, &sLevelInfo);
2036   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2037 
2038   rv = encoder_->ForceIntraFrame (true);
2039   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2040 
2041   ASSERT_TRUE (EncDecOneFrame (sParam.iPicWidth, sParam.iPicHeight, iEncFrameNum++, NULL));
2042 
2043   decoder_->GetOption (DECODER_OPTION_PROFILE, &iDecProfileIdc);
2044 
2045   if ((iEncProfileIdc != PRO_BASELINE) && (iEncProfileIdc != PRO_MAIN) && (iEncProfileIdc != PRO_HIGH)) {
2046     if (sParam.iEntropyCodingModeFlag) {
2047       iEncProfileIdc = PRO_HIGH;
2048     } else {
2049       iEncProfileIdc = PRO_BASELINE;
2050     }
2051   }
2052 
2053   ASSERT_TRUE (iDecProfileIdc == iEncProfileIdc) << "enc_profile = " << iEncProfileIdc << "  dec_profile = " <<
2054       iDecProfileIdc;
2055 
2056   //check whether the level is changed according to level limitation
2057   if (iEncLevelIdc != LEVEL_UNKNOWN) {
2058     uiLevel = CheckLevelLimitation (&sParam) ;
2059     if ((uiLevel == LEVEL_1_B) &&
2060         ((iDecProfileIdc == PRO_BASELINE) || (iDecProfileIdc == PRO_MAIN) || (iDecProfileIdc == PRO_EXTENDED))) {
2061       uiLevel = LEVEL_1_1;
2062     }
2063     if (iEncLevelIdc < uiLevel) {
2064       iEncLevelIdc = uiLevel;
2065     }
2066   }
2067   decoder_->GetOption (DECODER_OPTION_LEVEL, &iDecLevelIdc);
2068 
2069   if (iEncLevelIdc == LEVEL_UNKNOWN)
2070     ASSERT_TRUE (iDecLevelIdc != LEVEL_5_2) << "enc_level = " << iEncLevelIdc << "  dec_level = " << iDecLevelIdc;
2071   else
2072     ASSERT_TRUE (iDecLevelIdc == iEncLevelIdc) << "enc_level = " << iEncLevelIdc << "  dec_level = " << iDecLevelIdc;
2073 
2074   rv = encoder_->Uninitialize();
2075   ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
2076 }
2077 
TEST_F(EncodeDecodeTestAPI,AVCSVCExtensionCheck)2078 TEST_F (EncodeDecodeTestAPI, AVCSVCExtensionCheck) {
2079   int iWidth       = 640;
2080   int iHeight      = 360;
2081   float fFrameRate = rand() % 30 + 0.5f;
2082   int iTotalFrame  = 10; //total test enc frame num
2083   int iSliceNum    = 1;
2084 
2085   int iRet;
2086   int iSpatialLayerNumList[] = {1, 3};
2087   int iLoopNum = 5;
2088   for (int i = 0; i < iLoopNum; ++i) {
2089     // prepare params
2090     SEncParamExt sParam;
2091     encoder_->GetDefaultParams (&sParam);
2092     int iCurrSpatialLayerNum = iSpatialLayerNumList[rand() % 2];
2093     prepareParamDefault (iCurrSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
2094     sParam.bSimulcastAVC = rand() & 1; //0 or 1
2095     sParam.iRCMode = RC_TIMESTAMP_MODE;
2096     sParam.iNumRefFrame = 1;
2097     sParam.fMaxFrameRate = fFrameRate;
2098     sParam.sSpatialLayers[0].iSpatialBitrate = sParam.iTargetBitrate = 500;
2099     sParam.sSpatialLayers[1].iSpatialBitrate = sParam.iTargetBitrate = 1000;
2100     sParam.sSpatialLayers[2].iSpatialBitrate = sParam.iTargetBitrate = 2200;
2101     sParam.iTargetBitrate = 4000;
2102     //int TraceLevel = WELS_LOG_DEBUG;
2103     //encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2104     //decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &TraceLevel);
2105     iRet = encoder_->InitializeExt (&sParam);
2106     ASSERT_TRUE (iRet == cmResultSuccess) << "InitializeExt: iRet = " << iRet << " at " << sParam.iPicWidth << "x" <<
2107                                           sParam.iPicHeight;
2108     ASSERT_TRUE (InitialEncDec (iWidth, iHeight));
2109     int iLen = 0;
2110     for (int j = 0; j < iTotalFrame; ++j) {
2111       EncodeOneFrame (0);
2112       encToDecData (info, iLen);
2113       uint8_t cTypeByte;
2114       for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
2115         SLayerBSInfo* pLayerBsInfo = &info.sLayerInfo[iLayer];
2116         for (int iPacketNum = 0; iPacketNum < pLayerBsInfo->iNalCount; ++iPacketNum) {
2117           cTypeByte = (* (pLayerBsInfo->pBsBuf + 4)) & 0x1f;
2118           if (sParam.bSimulcastAVC) {
2119             EXPECT_TRUE (cTypeByte <= 8) << "simulcastAVC, spatial_id = " << pLayerBsInfo->uiSpatialId << ", typeByte = " <<
2120                                          cTypeByte;
2121           } else {
2122             if (pLayerBsInfo->uiSpatialId == 0)
2123               EXPECT_TRUE (cTypeByte <= 8 || cTypeByte == 14) << "simulcastSVC, spatial_id = 0, typeByte = " << cTypeByte;
2124             else
2125               EXPECT_TRUE (cTypeByte >= 14) << "simulcastSVC, spatial_id = " << pLayerBsInfo->uiSpatialId << ", typeByte = " <<
2126                                             cTypeByte;;
2127           }
2128         }
2129       }
2130     }
2131     iRet = encoder_->Uninitialize();
2132     ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2133   }
2134 }
2135 
TEST_F(EncodeDecodeTestAPI,UnsupportedVideoSizeInput)2136 TEST_F (EncodeDecodeTestAPI, UnsupportedVideoSizeInput) {
2137   int iWidth       = 640;
2138   int iHeight      = 360;
2139   float fFrameRate = rand() % 30 + 0.5f;
2140   int iSliceNum    = 1;
2141   int iRet;
2142 
2143   int iSrcWidth = rand() % 15 + 1;
2144   int iSrcHeight = rand() % 15 + 1;
2145 
2146   SEncParamExt sParam;
2147   encoder_->GetDefaultParams (&sParam);
2148   prepareParamDefault (1, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
2149   sParam.bSimulcastAVC = rand() & 1; //0 or 1
2150   sParam.iRCMode = RC_OFF_MODE;
2151   sParam.iNumRefFrame = 1;
2152   sParam.fMaxFrameRate = fFrameRate;
2153   iRet = encoder_->InitializeExt (&sParam);
2154   ASSERT_TRUE (iRet == cmResultSuccess) << "InitializeExt: iRet = " << iRet << " at " << sParam.iPicWidth << "x" <<
2155                                         sParam.iPicHeight;
2156 
2157 //   int TraceLevel = WELS_LOG_DEBUG;
2158 //   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2159   ASSERT_TRUE (InitialEncDec (iSrcWidth, iSrcHeight));
2160 
2161   iRet = encoder_->EncodeFrame (&EncPic, &info);
2162   ASSERT_TRUE (iRet == cmUnsupportedData) << "rv = " << iRet;
2163 
2164   iSrcWidth = iWidth;
2165   iSrcHeight = iHeight;
2166 
2167   ASSERT_TRUE (InitialEncDec (iSrcWidth, iSrcHeight));
2168 
2169   iRet = encoder_->EncodeFrame (&EncPic, &info);
2170 
2171   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2172 
2173   iRet = encoder_->Uninitialize();
2174   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2175 
2176 }
2177 
TEST_F(EncodeDecodeTestAPI,ScreenContent_LosslessLink0_EnableLongTermReference)2178 TEST_F (EncodeDecodeTestAPI,  ScreenContent_LosslessLink0_EnableLongTermReference) {
2179   int iWidth       = 2882;
2180   int iHeight      = 1808;
2181   float fFrameRate = rand() % 30 + 0.5f;
2182   int iSliceNum    = 1;
2183   int iRet;
2184 
2185   SEncParamExt sParam;
2186   encoder_->GetDefaultParams (&sParam);
2187   prepareParamDefault (1, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
2188   sParam.iUsageType = SCREEN_CONTENT_REAL_TIME;
2189   sParam.bEnableLongTermReference = 1;
2190   sParam.bIsLosslessLink = 0;
2191   //int TraceLevel = WELS_LOG_INFO;
2192   //encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2193   iRet = encoder_->InitializeExt (&sParam);
2194   ASSERT_TRUE (iRet == cmResultSuccess) << "InitializeExt: iRet = " << iRet << " at " << sParam.iPicWidth << "x" <<
2195                                         sParam.iPicHeight;
2196 
2197 
2198   ASSERT_TRUE (InitialEncDec (iWidth, iHeight));
2199 
2200   iRet = encoder_->EncodeFrame (&EncPic, &info);
2201 
2202   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2203 
2204   iRet = encoder_->Uninitialize();
2205   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2206 
2207 }
2208 
2209 
TEST_F(EncodeDecodeTestAPI,TemporalLayerChangeDuringEncoding)2210 TEST_F (EncodeDecodeTestAPI,  TemporalLayerChangeDuringEncoding) {
2211   int iWidth       = 320;
2212   int iHeight      = 192;
2213   float fFrameRate = 15;
2214   int iSliceNum    = 1;
2215   int iRet = 0;
2216   int iTotalFrame  = 20; //total test enc frame num
2217   int iFrameNum = 0;
2218   SEncParamExt sParam;
2219   encoder_->GetDefaultParams (&sParam);
2220   prepareParamDefault (1, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
2221   sParam.iTemporalLayerNum = 2;
2222 
2223 //  int TraceLevel = WELS_LOG_DEBUG;
2224 //  encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2225   iRet = encoder_->InitializeExt (&sParam);
2226   ASSERT_TRUE (iRet == cmResultSuccess) << "InitializeExt: iRet = " << iRet << " at " << sParam.iPicWidth << "x" <<
2227                                         sParam.iPicHeight;
2228 
2229   ASSERT_TRUE (InitialEncDec (iWidth, iHeight));
2230 
2231   int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
2232   do {
2233     FileInputStream fileStream;
2234     ASSERT_TRUE (fileStream.Open ("res/CiscoVT2people_320x192_12fps.yuv"));
2235 
2236     while (fileStream.read (buf_.data(), frameSize) == frameSize) {
2237       iRet = encoder_->EncodeFrame (&EncPic, &info);
2238       ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2239       if (iFrameNum == 5) {
2240         sParam.iTemporalLayerNum = 3;
2241         sParam.iTargetBitrate = 1500000;
2242         sParam.sSpatialLayers[0].iSpatialBitrate = 1500000;
2243         sParam.fMaxFrameRate = 30;
2244         //sSvcParam.sSpatialLayers[0].fFrameRate = 30;
2245         encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam);
2246       } else if (iFrameNum == 10) {
2247         sParam.iTemporalLayerNum = 1;
2248         sParam.iTargetBitrate = 500000;
2249         sParam.sSpatialLayers[0].iSpatialBitrate = 500000;
2250         sParam.fMaxFrameRate = 7.5;
2251         //sSvcParam.sSpatialLayers[0].fFrameRate = 7.5;
2252         encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam);
2253       } else if (iFrameNum == 15) {
2254         sParam.iTemporalLayerNum = 2;
2255         sParam.iTargetBitrate = 1000000;
2256         sParam.sSpatialLayers[0].iSpatialBitrate = 1000000;
2257         sParam.fMaxFrameRate = 15;
2258         //sSvcParam.sSpatialLayers[0].fFrameRate = 15;
2259         encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam);
2260       }
2261 
2262 
2263     }
2264     iFrameNum++;
2265   } while (iFrameNum < iTotalFrame);
2266 
2267   iRet = encoder_->Uninitialize();
2268   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2269 
2270 }
2271 
TEST_F(EncodeDecodeTestAPI,TemporalLayerChangeDuringEncoding_Specific)2272 TEST_F (EncodeDecodeTestAPI,  TemporalLayerChangeDuringEncoding_Specific) {
2273   int iWidth       = 320;
2274   int iHeight      = 192;
2275   float fFrameRate = 15;
2276   int iSliceNum    = 1;
2277   int iRet = 0;
2278   int iTotalFrame  = (rand() % 20) + 3;
2279   int iFrameNum = 0;
2280   SEncParamExt sParam;
2281   encoder_->GetDefaultParams (&sParam);
2282   prepareParamDefault (1, iSliceNum, iWidth, iHeight, fFrameRate, &sParam);
2283 
2284   int originalTemporalLayerNum = 1;
2285   int originalBR = 500000;
2286   float originalFR = 7.5;
2287   int iSteps[3] = {2, 1, 3};
2288   int iStepIdx = 0;
2289   bool bSetOption = false;
2290 
2291   sParam.iTemporalLayerNum = originalTemporalLayerNum;
2292   sParam.iNumRefFrame = 1;
2293 
2294 // int TraceLevel = WELS_LOG_INFO;
2295 //  encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
2296   iRet = encoder_->InitializeExt (&sParam);
2297   ASSERT_TRUE (iRet == cmResultSuccess) << "InitializeExt: iRet = " << iRet << " at " << sParam.iPicWidth << "x" <<
2298                                         sParam.iPicHeight;
2299 
2300   ASSERT_TRUE (InitialEncDec (iWidth, iHeight));
2301 
2302   int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
2303   do {
2304     FileInputStream fileStream;
2305     ASSERT_TRUE (fileStream.Open ("res/CiscoVT2people_320x192_12fps.yuv"));
2306 
2307     while (fileStream.read (buf_.data(), frameSize) == frameSize) {
2308 
2309       if ((iStepIdx < 3) && (iFrameNum == ((iTotalFrame / 3) * (iStepIdx + 1)))) {
2310         sParam.iTemporalLayerNum = originalTemporalLayerNum * iSteps[iStepIdx];
2311         sParam.iTargetBitrate = sParam.sSpatialLayers[0].iSpatialBitrate = originalBR * iSteps[iStepIdx];
2312         sParam.fMaxFrameRate = sParam.sSpatialLayers[0].fFrameRate = static_cast <float> (originalFR * pow (2.0f, iSteps[iStepIdx]));
2313         encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam);
2314 
2315         bSetOption = true;
2316         iStepIdx += 1;
2317       }
2318 
2319       iRet = encoder_->EncodeFrame (&EncPic, &info);
2320       EXPECT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2321 
2322       if (bSetOption) {
2323         if ((iStepIdx == 1) || (iStepIdx == 3)) {
2324           EXPECT_TRUE (info.eFrameType == videoFrameTypeIDR) << "iStepIdx=" << iStepIdx << "iFrameNum=" << iFrameNum <<
2325               "iTotalFrame=" << iTotalFrame;
2326         } else {
2327           EXPECT_TRUE (info.eFrameType != videoFrameTypeIDR) << "iStepIdx=" << iStepIdx << "iFrameNum=" << iFrameNum <<
2328               "iTotalFrame=" << iTotalFrame;
2329         }
2330 
2331         bSetOption = false;
2332       }
2333 
2334 
2335     }
2336     iFrameNum++;
2337   } while (iFrameNum < iTotalFrame);
2338 
2339   iRet = encoder_->Uninitialize();
2340   ASSERT_TRUE (iRet == cmResultSuccess) << "rv = " << iRet;
2341 
2342 }
2343 
TEST_F(EncodeDecodeTestAPI,ENCODER_OPTION_IDR_INTERVAL)2344 TEST_F (EncodeDecodeTestAPI, ENCODER_OPTION_IDR_INTERVAL) {
2345   int iSpatialLayerNum = 1;
2346   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
2347   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
2348   float fFrameRate = rand() + 0.5f;
2349   int iSliceNum        = 1;
2350   encoder_->GetDefaultParams (&param_);
2351   prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
2352   param_.iTemporalLayerNum = 1;
2353 
2354   int iTraceLevel = WELS_LOG_QUIET;
2355   int rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
2356   EXPECT_TRUE (rv == cmResultSuccess);
2357 
2358   rv = encoder_->InitializeExt (&param_);
2359   ASSERT_TRUE (rv == cmResultSuccess);
2360 
2361   InitialEncDec (param_.iPicWidth, param_.iPicHeight);
2362   EncodeOneFrame (0);
2363   EXPECT_TRUE (info.eFrameType == videoFrameTypeIDR);
2364 
2365   int iLastIdrIdx = 0;
2366   int iFrame = 1;
2367   int iTtlAttempt = (rand() % 5) + 2;
2368   for (int iAtt = 0; iAtt < iTtlAttempt; iAtt++) {
2369     int kiTargetIntraPeriod = WelsClip3 ((rand() % ENCODE_FRAME_NUM) - 1, -1, ENCODE_FRAME_NUM);
2370     rv = encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &kiTargetIntraPeriod);
2371     EXPECT_TRUE (rv == cmResultSuccess);
2372 
2373     int iEncFrameNum = kiTargetIntraPeriod * 3;
2374     for (int i = 0; i < iEncFrameNum; i++) {
2375       EncodeOneFrame (0);
2376 
2377       if ((kiTargetIntraPeriod <= 0) || (((iFrame - iLastIdrIdx) % kiTargetIntraPeriod) == 0)) {
2378         EXPECT_TRUE (info.eFrameType == videoFrameTypeIDR) << "kiTargetIntraPeriod " << kiTargetIntraPeriod <<
2379             " info.eFrameType " << info.eFrameType << " Frame " << i;
2380         iLastIdrIdx = iFrame;
2381       } else {
2382         EXPECT_FALSE (info.eFrameType == videoFrameTypeIDR);
2383       }
2384 
2385       iFrame ++;
2386     }
2387   }
2388 }
2389