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 = ¶m_.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 = ¶m_.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 (¶m_);
307 prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, ¶m_);
308
309 int rv = encoder_->InitializeExt (¶m_);
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, ¶m_);
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 (¶m_);
357 prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, ¶m_);
358
359 int rv = encoder_->InitializeExt (¶m_);
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, ¶m_);
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 (¶m_);
954 prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, ¶m_);
955
956 int rv = encoder_->InitializeExt (¶m_);
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 (¶m_);
1074 prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, ¶m_);
1075
1076 //set flag of bSimulcastAVC
1077 param_.bSimulcastAVC = true;
1078
1079 int rv = encoder_->InitializeExt (¶m_);
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 (¶m_, 0, sizeof (SEncParamExt));
1332 encoder_->GetDefaultParams (¶m_);
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 (¶m_);
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 (¶m_);
1448 prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, ¶m_);
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 (¶m_);
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 (¶m_);
2351 prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, ¶m_);
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 (¶m_);
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