History

moving test cases to specific files to avoid the too long encode_decode_api_test.cpp

sijchen committed 10 years ago

Commit 46667581 parent f679da97 files · +3619 −3554Browse files

Showing the changes to test/api/encode_options_test.cpp (1 of 7 files). Show all

Unified · Split

test/api/encode_options_test.cpp+1671−0
@@ -0,0 +1,1671 @@
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+
13+void 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+ ASSERT_TRUE (buf_.Length() == (size_t)frameSize);
20+
21+ memset (&EncPic, 0, sizeof (SSourcePicture));
22+ EncPic.iPicWidth = iWidth;
23+ EncPic.iPicHeight = iHeight;
24+ EncPic.iColorFormat = videoFormatI420;
25+ EncPic.iStride[0] = EncPic.iPicWidth;
26+ EncPic.iStride[1] = EncPic.iStride[2] = EncPic.iPicWidth >> 1;
27+ EncPic.pData[0] = buf_.data();
28+ EncPic.pData[1] = EncPic.pData[0] + iWidth * iHeight;
29+ EncPic.pData[2] = EncPic.pData[1] + (iWidth * iHeight >> 2);
30+
31+ //for decoder
32+ memset (&info, 0, sizeof (SFrameBSInfo));
33+
34+ //set a fixed random value
35+ iRandValue = rand() % 256;
36+}
37+
38+void EncodeDecodeTestAPIBase::RandomParamExtCombination() {
39+
40+ param_.iPicWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 2, MAX_WIDTH);
41+ param_.iPicHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 2, MAX_HEIGHT);
42+
43+ param_.fMaxFrameRate = rand() % FRAME_RATE_RANGE + 0.5f;
44+ param_.iUsageType = static_cast<EUsageType> (rand() % 2);
45+ param_.iTemporalLayerNum = rand() % TEMPORAL_LAYER_NUM_RANGE;
46+ param_.iSpatialLayerNum = rand() % SPATIAL_LAYER_NUM_RANGE;
47+
48+ param_.uiIntraPeriod = rand() - 1;
49+ param_.iNumRefFrame = AUTO_REF_PIC_COUNT;
50+ param_.iMultipleThreadIdc = rand();
51+
52+ int iValue = rand() % 7;
53+ switch (iValue) {
54+ case 0:
55+ param_.eSpsPpsIdStrategy = CONSTANT_ID;
56+ break;
57+ case 0x01:
58+ param_.eSpsPpsIdStrategy = INCREASING_ID;
59+ break;
60+ case 0x02:
61+ param_.eSpsPpsIdStrategy = SPS_LISTING;
62+ break;
63+ case 0x03:
64+ param_.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
65+ break;
66+ case 0x06:
67+ param_.eSpsPpsIdStrategy = SPS_PPS_LISTING;
68+ break;
69+ default:
70+ param_.eSpsPpsIdStrategy = CONSTANT_ID;
71+ break;
72+ }
73+ param_.bPrefixNalAddingCtrl = (rand() % 2 == 0) ? false : true;
74+ param_.bEnableSSEI = (rand() % 2 == 0) ? false : true;
75+ param_.iPaddingFlag = rand() % 2;
76+
77+ //LTR
78+ param_.bEnableLongTermReference = (rand() % 2 == 0) ? false : true;
79+ param_.bIsLosslessLink = (rand() % 2 == 0) ? false : true;
80+ param_.iLTRRefNum = rand();
81+ param_.iLtrMarkPeriod = rand();
82+
83+ //loop filter
84+ param_.iLoopFilterDisableIdc = rand() % 7;
85+ param_.iLoopFilterAlphaC0Offset = rand();
86+ param_.iLoopFilterBetaOffset = rand();
87+
88+ param_.bEnableDenoise = (rand() % 2 == 0) ? false : true;
89+ param_.bEnableBackgroundDetection = (rand() % 2 == 0) ? false : true;
90+ param_.bEnableAdaptiveQuant = (rand() % 2 == 0) ? false : true;
91+ param_.bEnableFrameCroppingFlag = (rand() % 2 == 0) ? false : true;
92+ param_.bEnableSceneChangeDetect = (rand() % 2 == 0) ? false : true;
93+
94+ //for rc
95+ param_.iRCMode = static_cast<RC_MODES> (rand() % RC_MODE_RANGE - 1);
96+ param_.iMaxBitrate = rand() % BIT_RATE_RANGE;
97+ param_.iTargetBitrate = rand() % BIT_RATE_RANGE;
98+ param_.iMaxQp = rand() % QP_RANGE;
99+ param_.iMinQp = rand() % QP_RANGE;
100+ param_.uiMaxNalSize = rand();
101+ param_.bEnableFrameSkip = (rand() % 2 == 0) ? false : true;
102+
103+ for (int iSpatialIdx = 0; iSpatialIdx < param_.iSpatialLayerNum; iSpatialIdx++) {
104+ if (iSpatialIdx < MAX_SPATIAL_LAYER_NUM) {
105+ SSpatialLayerConfig* pSpatialLayer = &param_.sSpatialLayers[iSpatialIdx];
106+
107+ //to do: profile and level id
108+ //pSpatialLayer->uiProfileIdc = 0;
109+ //pSpatialLayer->uiLevelIdc = 0;
110+ pSpatialLayer->iVideoWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 2, MAX_WIDTH);
111+ pSpatialLayer->iVideoHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 2, MAX_HEIGHT);
112+ pSpatialLayer->fFrameRate = rand() % FRAME_RATE_RANGE + 0.5f;
113+ pSpatialLayer->iMaxSpatialBitrate = rand() % BIT_RATE_RANGE;
114+ pSpatialLayer->iSpatialBitrate = rand() % BIT_RATE_RANGE;
115+
116+
117+ pSpatialLayer->sSliceArgument.uiSliceMode = static_cast<SliceModeEnum> (rand() % SLICE_MODE_NUM);
118+ if (pSpatialLayer->sSliceArgument.uiSliceMode != SM_SIZELIMITED_SLICE) {
119+ param_.uiMaxNalSize = 0;
120+ }
121+ pSpatialLayer->sSliceArgument.uiSliceNum = rand();
122+ pSpatialLayer->sSliceArgument.uiSliceSizeConstraint = rand();
123+ }
124+ }
125+}
126+
127+void EncodeDecodeTestAPIBase::ValidateParamExtCombination() {
128+
129+ bool bDynSliceModeFlag = false;
130+ unsigned int uiGOPSize = 0;
131+ unsigned int uiSliceNum = 0;
132+ int iTotalBitRate = 0;
133+ int iMinQP = 0;
134+
135+ param_.iPicWidth = WELS_CLIP3 (param_.iPicWidth, 2, MAX_WIDTH);
136+ param_.iPicHeight = WELS_CLIP3 (param_.iPicHeight, 2, MAX_HEIGHT);
137+ param_.fMaxFrameRate = WELS_CLIP3 (param_.fMaxFrameRate, MIN_FRAME_RATE, MAX_FRAME_RATE);
138+ param_.iTemporalLayerNum = WELS_CLIP3 (param_.iTemporalLayerNum, 1, MAX_TEMPORAL_LAYER_NUM);
139+
140+ if (CAMERA_VIDEO_REAL_TIME == param_.iUsageType)
141+ param_.iSpatialLayerNum = WELS_CLIP3 (param_.iSpatialLayerNum, 1, MAX_SPATIAL_LAYER_NUM);
142+ else
143+ param_.iSpatialLayerNum = 1;
144+
145+ //IntraPeriod
146+ uiGOPSize = 1 << (param_.iTemporalLayerNum - 1);
147+ param_.uiIntraPeriod -= param_.uiIntraPeriod % uiGOPSize;
148+
149+ //RefNum
150+ int32_t iRefUpperBound = (param_.iUsageType == CAMERA_VIDEO_REAL_TIME) ?
151+ MAX_REFERENCE_PICTURE_COUNT_NUM_CAMERA : MAX_REFERENCE_PICTURE_COUNT_NUM_SCREEN;
152+ param_.iNumRefFrame = WELS_CLIP3 (param_.iNumRefFrame, MIN_REF_PIC_COUNT, iRefUpperBound);
153+
154+ //to do: will add more validate logic for thread number
155+ param_.iMultipleThreadIdc = 1;
156+
157+ //LTR
158+ //iLTRRefNum: not supported to set it arbitrary yet
159+ if (true == param_.bEnableLongTermReference) {
160+ param_.iLTRRefNum = (SCREEN_CONTENT_REAL_TIME == param_.iUsageType) ? LONG_TERM_REF_NUM_SCREEN : LONG_TERM_REF_NUM;
161+ param_.iLtrMarkPeriod = (0 == param_.iLtrMarkPeriod) ? 1 : param_.iLtrMarkPeriod;
162+
163+ } else {
164+ param_.iLTRRefNum = 0;
165+ }
166+
167+ //loop filter
168+ param_.iLoopFilterDisableIdc = param_.iLoopFilterDisableIdc % LOOP_FILTER_IDC_NUM;
169+ param_.iLoopFilterAlphaC0Offset = param_.iLoopFilterAlphaC0Offset % (2 * LOOF_FILTER_OFFSET_RANGE + 1) -
170+ LOOF_FILTER_OFFSET_RANGE;
171+ param_.iLoopFilterBetaOffset = param_.iLoopFilterBetaOffset % (2 * LOOF_FILTER_OFFSET_RANGE + 1) -
172+ LOOF_FILTER_OFFSET_RANGE;
173+
174+ for (int iSpatialIdx = 0; iSpatialIdx < param_.iSpatialLayerNum; iSpatialIdx++) {
175+ SSpatialLayerConfig* pSpatialLayer = &param_.sSpatialLayers[iSpatialIdx];
176+ pSpatialLayer->iVideoWidth = param_.iPicWidth >> (param_.iSpatialLayerNum - 1 - iSpatialIdx);
177+ pSpatialLayer->iVideoHeight = param_.iPicHeight >> (param_.iSpatialLayerNum - 1 - iSpatialIdx);
178+ pSpatialLayer->fFrameRate = param_.fMaxFrameRate;
179+
180+ pSpatialLayer->iMaxSpatialBitrate = WELS_CLIP3 (pSpatialLayer->iMaxSpatialBitrate, 1, BIT_RATE_RANGE);
181+ pSpatialLayer->iSpatialBitrate = WELS_CLIP3 (pSpatialLayer->iSpatialBitrate, 1, pSpatialLayer->iMaxSpatialBitrate);
182+ iTotalBitRate += pSpatialLayer->iSpatialBitrate;
183+
184+ uiSliceNum = pSpatialLayer->sSliceArgument.uiSliceNum;
185+ pSpatialLayer->sSliceArgument.uiSliceNum = WELS_CLIP3 (uiSliceNum, 1, MAX_SLICES_NUM);
186+ pSpatialLayer->sSliceArgument.uiSliceSizeConstraint = 0;
187+
188+
189+ //for SM_FIXEDSLCNUM_SLICE
190+ // to do will add this when GOM bug fixed
191+ if (SM_FIXEDSLCNUM_SLICE == pSpatialLayer->sSliceArgument.uiSliceMode) {
192+ pSpatialLayer->sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
193+ }
194+
195+ //for slice mode = SM_SIZELIMITED_SLICE
196+ if (SM_SIZELIMITED_SLICE == pSpatialLayer->sSliceArgument.uiSliceMode) {
197+ bDynSliceModeFlag = true;
198+ }
199+
200+ //for slice mode = SM_RASTER_SLICE
201+ if (SM_RASTER_SLICE == pSpatialLayer->sSliceArgument.uiSliceMode) {
202+ if (0 != pSpatialLayer->sSliceArgument.uiSliceMbNum[0]) {
203+ SliceParamValidationForMode2 (iSpatialIdx);
204+ } else {
205+ SliceParamValidationForMode3 (iSpatialIdx);
206+ }
207+ }
208+ }
209+
210+ //for RC
211+ if ((RC_QUALITY_MODE == param_.iRCMode) || (RC_BITRATE_MODE == param_.iRCMode)) {
212+ param_.bEnableFrameSkip = true;
213+ }
214+ if (param_.iTargetBitrate < iTotalBitRate) {
215+ param_.iTargetBitrate = iTotalBitRate;
216+ }
217+ if (param_.iMaxBitrate < param_.iTargetBitrate) {
218+ param_.iMaxBitrate = param_.iTargetBitrate;
219+ }
220+ param_.iMaxQp = WELS_CLIP3 (param_.iMaxQp, MIN_QP, MAX_QP);
221+ param_.iMinQp = WELS_CLIP3 (param_.iMinQp, MIN_QP, MAX_QP);
222+ iMinQP = (param_.iMaxQp < param_.iMinQp) ? param_.iMaxQp : param_.iMinQp;
223+ param_.iMaxQp = (param_.iMaxQp > param_.iMinQp) ? param_.iMaxQp : param_.iMinQp;
224+ param_.iMinQp = iMinQP;
225+ param_.uiMaxNalSize = 0;
226+
227+ //for slice mode = SM_SIZELIMITED_SLICE
228+ if (true == bDynSliceModeFlag) {
229+ SliceParamValidationForMode4();
230+ }
231+
232+}
233+
234+
235+void EncodeDecodeTestAPIBase::SliceParamValidationForMode2 (int iSpatialIdx) {
236+
237+ unsigned int uiMbWidth = 0;
238+ unsigned int uiMbHeight = 0;
239+ unsigned int uiMbNumInFrame = 0;
240+ unsigned int uiCountMb = 0;
241+ unsigned int uiSliceIdx = 0;
242+ unsigned int uiActualSliceCount = 0;
243+
244+ uiMbWidth = (param_.iPicWidth + 15) >> 4;
245+ uiMbHeight = (param_.iPicHeight + 15) >> 4;
246+ uiMbNumInFrame = uiMbWidth * uiMbHeight;
247+
248+ uiSliceIdx = 0;
249+ while (uiSliceIdx < MAX_SLICES_NUM) {
250+ param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMbNum[uiSliceIdx] = rand() % uiMbNumInFrame;
251+ uiCountMb += param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMbNum[uiSliceIdx];
252+ uiActualSliceCount = uiSliceIdx + 1;
253+
254+ if (uiCountMb >= uiMbNumInFrame) {
255+ break;
256+ }
257+
258+ ++ uiSliceIdx;
259+ }
260+
261+ if (uiCountMb >= uiMbNumInFrame) {
262+ param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMbNum[uiActualSliceCount - 1] -=
263+ (uiCountMb - uiMbNumInFrame);
264+
265+ } else {
266+ param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMbNum[uiActualSliceCount - 1 ] +=
267+ (uiMbNumInFrame - uiCountMb);
268+ }
269+ param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceNum = uiActualSliceCount;
270+
271+}
272+void EncodeDecodeTestAPIBase::SliceParamValidationForMode3 (int iSpatialIdx) {
273+
274+ unsigned int uiMbHeight = 0;
275+
276+ uiMbHeight = (param_.iPicHeight + 15) >> 4;
277+
278+ //change slice mode to SM_SINGLE_SLICE
279+ if (uiMbHeight > MAX_SLICES_NUM) {
280+ param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMode = SM_SINGLE_SLICE;
281+ }
282+
283+}
284+
285+void EncodeDecodeTestAPIBase::SliceParamValidationForMode4() {
286+ //slice mode of all spatial layer should be set as SM_SIZELIMITED_SLICE
287+ for (int iSpatialIdx = 0; iSpatialIdx < param_.iSpatialLayerNum; iSpatialIdx++) {
288+ param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceSizeConstraint = 600;
289+ param_.sSpatialLayers[iSpatialIdx].sSliceArgument.uiSliceMode = SM_SIZELIMITED_SLICE;
290+ }
291+ param_.uiMaxNalSize = 1500;
292+}
293+
294+TEST_F (EncodeDecodeTestAPI, SetOptionEncParamExt) {
295+ int iSpatialLayerNum = 4;
296+ int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
297+ int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
298+ float fFrameRate = rand() + 0.5f;
299+ int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
300+ int iSliceNum = 1;
301+ encoder_->GetDefaultParams (&param_);
302+ prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
303+
304+ int rv = encoder_->InitializeExt (&param_);
305+ ASSERT_TRUE (rv == cmResultSuccess);
306+
307+ int iTraceLevel = WELS_LOG_QUIET;
308+ rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
309+ ASSERT_TRUE (rv == cmResultSuccess);
310+
311+ for (int i = 0; i < iEncFrameNum; i++) {
312+ int iResult;
313+ int len = 0;
314+ unsigned char* pData[3] = { NULL };
315+
316+ RandomParamExtCombination();
317+ iResult = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &param_);
318+ //ValidateParamExtCombination();
319+ //ASSERT_TRUE (iResult == cmResultSuccess);
320+ //to do
321+ // currently, there are still some error cases even though under condition cmResultSuccess == iResult
322+ // so need to enhance the validation check for any random value of each variable in ParamExt
323+
324+ if (cmResultSuccess == iResult) {
325+ InitialEncDec (param_.iPicWidth, param_.iPicHeight);
326+ EncodeOneFrame (0);
327+ encToDecData (info, len);
328+ pData[0] = pData[1] = pData[2] = 0;
329+ memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
330+
331+ iResult = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
332+ ASSERT_TRUE (iResult == cmResultSuccess);
333+ iResult = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
334+ ASSERT_TRUE (iResult == cmResultSuccess);
335+ EXPECT_EQ (dstBufInfo_.iBufferStatus, 1);
336+ }
337+ }
338+
339+ iTraceLevel = WELS_LOG_ERROR;
340+ encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
341+}
342+
343+struct EncodeDecodeParamBase {
344+ int width;
345+ int height;
346+ float frameRate;
347+ int iTarBitrate;
348+};
349+
350+//#define DEBUG_FILE_SAVE2
351+TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING1) {
352+
353+ int iWidth = GetRandWidth();
354+ int iHeight = GetRandHeight();
355+ float fFrameRate = rand() + 0.5f;
356+ int iEncFrameNum = 0;
357+ int iSpatialLayerNum = 1;
358+ int iSliceNum = 1;
359+
360+ // prepare params
361+ SEncParamExt sParam1;
362+ SEncParamExt sParam2;
363+ SEncParamExt sParam3;
364+ encoder_->GetDefaultParams (&sParam1);
365+ prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
366+ sParam1.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
367+ //prepare param2
368+ memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
369+ while (GET_MB_WIDTH (sParam2.iPicWidth) == GET_MB_WIDTH (sParam1.iPicWidth)) {
370+ sParam2.iPicWidth = GetRandWidth();
371+ }
372+ prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
373+ sParam2.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
374+ //prepare param3
375+ memcpy (&sParam3, &sParam1, sizeof (SEncParamExt));
376+ while (GET_MB_WIDTH (sParam3.iPicHeight) == GET_MB_WIDTH (sParam1.iPicHeight)) {
377+ sParam3.iPicHeight = GetRandHeight();
378+ }
379+ prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam3.iPicWidth, sParam3.iPicHeight, fFrameRate, &sParam3);
380+ sParam3.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
381+
382+ //prepare output if needed
383+ FILE* fEnc = NULL;
384+#ifdef DEBUG_FILE_SAVE2
385+ fEnc = fopen ("enc2.264", "wb");
386+#endif
387+
388+ // Test part#1
389+ // step#1: pParam1
390+ //int TraceLevel = WELS_LOG_INFO;
391+ //encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
392+ int rv = encoder_->InitializeExt (&sParam1);
393+ ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
394+ sParam1.iPicHeight;
395+ EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
396+
397+ // new IDR
398+ rv = encoder_->ForceIntraFrame (true);
399+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
400+ EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
401+
402+ // step#2: pParam2
403+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
404+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam2.iPicWidth << "x" <<
405+ sParam2.iPicHeight;
406+ EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
407+
408+ // new IDR
409+ rv = encoder_->ForceIntraFrame (true);
410+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
411+ EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
412+
413+ // step#3: back to pParam1
414+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
415+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
416+ sParam1.iPicHeight;
417+ EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
418+
419+ // step#4: back to pParam2
420+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
421+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv << sParam2.iPicWidth << sParam2.iPicHeight;
422+ EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
423+
424+#ifdef DEBUG_FILE_SAVE2
425+ fclose (fEnc);
426+#endif
427+ rv = encoder_->Uninitialize();
428+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
429+
430+ // Test part#2
431+ // step#1: pParam1
432+ rv = encoder_->InitializeExt (&sParam1);
433+ ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt Failed: rv = " << rv;
434+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
435+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
436+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam3);
437+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam3: rv = " << rv;
438+
439+#ifdef DEBUG_FILE_SAVE2
440+ fEnc = fopen ("enc3.264", "wb");
441+#endif
442+ iEncFrameNum = 0;
443+ EncDecOneFrame (sParam3.iPicWidth, sParam3.iPicHeight, iEncFrameNum++, fEnc);
444+
445+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
446+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
447+ EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
448+
449+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
450+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
451+ EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
452+
453+#ifdef DEBUG_FILE_SAVE2
454+ fclose (fEnc);
455+#endif
456+ rv = encoder_->Uninitialize();
457+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
458+}
459+
460+//#define DEBUG_FILE_SAVE5
461+TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING2) {
462+ //usage 3: 2 Params with different num_ref, encode IDR0, P1, IDR2;
463+ //the bs will show two SPS and different PPS
464+
465+ int iWidth = GetRandWidth();
466+ int iHeight = GetRandHeight();
467+ float fFrameRate = rand() + 0.5f;
468+ int iEncFrameNum = 0;
469+ int iSpatialLayerNum = 1;
470+ int iSliceNum = 1;
471+
472+ // prepare params
473+ SEncParamExt sParam1;
474+ SEncParamExt sParam2;
475+ encoder_->GetDefaultParams (&sParam1);
476+ prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
477+ sParam1.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
478+ sParam1.iTemporalLayerNum = 1;
479+ //prepare param2
480+ memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
481+ prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
482+ sParam2.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
483+ sParam2.iTemporalLayerNum = 3;
484+
485+ //prepare output if needed
486+ FILE* fEnc = NULL;
487+#ifdef DEBUG_FILE_SAVE5
488+ fEnc = fopen ("encID2.264", "wb");
489+#endif
490+
491+ // step#1: pParam1
492+ int rv = encoder_->InitializeExt (&sParam1);
493+ ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
494+ sParam1.iPicHeight;
495+
496+ // step#2: pParam2
497+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
498+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
499+
500+ // step#3: set back to pParam1, with a smaller num_ref, it still uses the previous SPS
501+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
502+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam1: rv = " << rv;
503+ EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
504+
505+ // new IDR, PPS increases
506+ rv = encoder_->ForceIntraFrame (true);
507+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
508+ EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
509+
510+ rv = encoder_->Uninitialize();
511+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
512+
513+#ifdef DEBUG_FILE_SAVE5
514+ fclose (fEnc);
515+#endif
516+}
517+
518+TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_LISTING_AND_PPS_INCREASING3) {
519+
520+ int iWidth = GetRandWidth();
521+ int iHeight = GetRandHeight();
522+ float fFrameRate = rand() + 0.5f;
523+ int iEncFrameNum = 0;
524+ int iSpatialLayerNum = 1;
525+ int iSliceNum = 1;
526+
527+ // prepare params
528+ SEncParamExt sParam1;
529+ SEncParamExt sParam2;
530+ encoder_->GetDefaultParams (&sParam1);
531+ prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
532+ sParam1.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
533+
534+ //prepare output if needed
535+ FILE* fEnc = NULL;
536+#ifdef DEBUG_FILE_SAVE2
537+ fEnc = fopen ("enc4.264", "wb");
538+#endif
539+
540+ // step#1: pParam1
541+ int rv = encoder_->InitializeExt (&sParam1);
542+ ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt Failed: rv = " << rv;
543+
544+ int max_count = 65; // make it more then twice as MAX_SPS_COUNT
545+ std::vector<int> vWidthTable;
546+ vWidthTable.push_back (GET_MB_WIDTH (sParam1.iPicWidth));
547+
548+ std::vector<int>::iterator vWidthTableIt;
549+ for (int times = 0; times < max_count; times++) {
550+ //prepare param2
551+ memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
552+ do {
553+ sParam2.iPicWidth = GetRandWidth();
554+ vWidthTableIt = std::find (vWidthTable.begin(), vWidthTable.end(), GET_MB_WIDTH (sParam2.iPicWidth));
555+ } while (vWidthTableIt != vWidthTable.end());
556+ vWidthTable.push_back (GET_MB_WIDTH (sParam2.iPicWidth));
557+ prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
558+ sParam2.eSpsPpsIdStrategy = SPS_LISTING_AND_PPS_INCREASING;
559+
560+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
561+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv << ", sParam2.iPicWidth=" <<
562+ sParam2.iPicWidth;
563+ } // end of setting loop
564+
565+ EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
566+
567+#ifdef DEBUG_FILE_SAVE2
568+ fclose (fEnc);
569+#endif
570+ rv = encoder_->Uninitialize();
571+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
572+}
573+
574+//#define DEBUG_FILE_SAVE6
575+TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING1) {
576+ //usage 1: 1 resolution Params, encode IDR0, P1, IDR2;
577+ //the bs will show same SPS and different PPS
578+ // PPS: pic_parameter_set_id 1 ( 0)
579+ // PPS: seq_parameter_set_id 1 ( 0)
580+ // PPS: pic_parameter_set_id 010 ( 1)
581+ // PPS: seq_parameter_set_id 1 ( 0)
582+ // SH: slice_type 011 ( 2)
583+ // SH: pic_parameter_set_id 1 ( 0)
584+ // SH: slice_type 1 ( 0)
585+ // SH: pic_parameter_set_id 1 ( 0)
586+ // SH: slice_type 011 ( 2)
587+ // SH: pic_parameter_set_id 010 ( 1)
588+ int iWidth = GetRandWidth();
589+ int iHeight = GetRandHeight();
590+ float fFrameRate = rand() + 0.5f;
591+ int iEncFrameNum = 0;
592+ int iSpatialLayerNum = 1;
593+ int iSliceNum = 1;
594+
595+ // prepare params
596+ SEncParamExt sParam1;
597+ encoder_->GetDefaultParams (&sParam1);
598+ prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
599+ sParam1.eSpsPpsIdStrategy = SPS_PPS_LISTING;
600+
601+ //prepare output if needed
602+ FILE* fEnc = NULL;
603+#ifdef DEBUG_FILE_SAVE6
604+ fEnc = fopen ("encLIST1.264", "wb");
605+#endif
606+
607+ // step#1: pParam1
608+ int rv = encoder_->InitializeExt (&sParam1);
609+ ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
610+ sParam1.iPicHeight;
611+ EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
612+ EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
613+
614+ // new IDR
615+ rv = encoder_->ForceIntraFrame (true);
616+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
617+ EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
618+
619+ rv = encoder_->Uninitialize();
620+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
621+
622+#ifdef DEBUG_FILE_SAVE6
623+ fclose (fEnc);
624+#endif
625+}
626+
627+TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING2) {
628+ //usage 2: 2 resolution Params, encode IDR0, IDR1, IDR2;
629+ //the bs will show two SPS and different PPS
630+ // === SPS LIST ===
631+ //SPS: seq_parameter_set_id 1 ( 0) -- PARAM1
632+ //SPS: seq_parameter_set_id 010 ( 1) -- PARAM2
633+ // === PPS LIST ===
634+ //PPS: pic_parameter_set_id 1 ( 0)
635+ //PPS: seq_parameter_set_id 1 ( 0)
636+ //PPS: pic_parameter_set_id 010 ( 1)
637+ //PPS: seq_parameter_set_id 010 ( 1)
638+ //PPS: pic_parameter_set_id 011 ( 2) -- PPS2 - SPS0
639+ //PPS: seq_parameter_set_id 1 ( 0)
640+ //PPS: pic_parameter_set_id 00100 ( 3) -- PPS3 - SPS1
641+ //PPS: seq_parameter_set_id 010 ( 1)
642+ //PPS: pic_parameter_set_id 00101 ( 4) -- PPS4 - SPS0
643+ //PPS: seq_parameter_set_id 1 ( 0)
644+ // === VCL LAYER ===
645+ //SH: slice_type 011 ( 2) -- PARAM2
646+ //SH: pic_parameter_set_id 010 ( 1) -- PPS1 - SPS1 - PARAM2
647+ //SH: slice_type 011 ( 2) -- PARAM1
648+ //SH: pic_parameter_set_id 011 ( 2) -- PPS2 - SPS0 - PARAM1
649+ //SH: slice_type 011 ( 2) -- PARAM1
650+ //SH: pic_parameter_set_id 00101 ( 4) -- PPS4 - SPS0 - PARAM1
651+
652+ int iWidth = GetRandWidth();
653+ int iHeight = GetRandHeight();
654+ float fFrameRate = rand() + 0.5f;
655+ int iEncFrameNum = 0;
656+ int iSpatialLayerNum = 1;
657+ int iSliceNum = 1;
658+
659+ // prepare params
660+ SEncParamExt sParam1;
661+ SEncParamExt sParam2;
662+ encoder_->GetDefaultParams (&sParam1);
663+ prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
664+ sParam1.eSpsPpsIdStrategy = SPS_PPS_LISTING;
665+ //prepare param2
666+ memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
667+ while (GET_MB_WIDTH (sParam2.iPicWidth) == GET_MB_WIDTH (sParam1.iPicWidth)) {
668+ sParam2.iPicWidth = GetRandWidth();
669+ }
670+ prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
671+ sParam2.eSpsPpsIdStrategy = SPS_PPS_LISTING;
672+
673+ //prepare output if needed
674+ FILE* fEnc = NULL;
675+#ifdef DEBUG_FILE_SAVE5
676+ fEnc = fopen ("encLIST2.264", "wb");
677+#endif
678+
679+ // step#1: pParam1
680+ int rv = encoder_->InitializeExt (&sParam1);
681+ ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
682+ sParam1.iPicHeight;
683+
684+ // step#2: pParam2
685+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
686+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
687+ EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
688+
689+ // step#3: back to pParam1, SHOULD NOT encounter ERROR
690+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam1);
691+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
692+ sParam1.iPicHeight;
693+ EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
694+
695+ // new IDR
696+ rv = encoder_->ForceIntraFrame (true);
697+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
698+ EncDecOneFrame (sParam1.iPicWidth, sParam1.iPicHeight, iEncFrameNum++, fEnc);
699+
700+ rv = encoder_->Uninitialize();
701+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
702+
703+#ifdef DEBUG_FILE_SAVE5
704+ fclose (fEnc);
705+#endif
706+}
707+
708+TEST_F (EncodeDecodeTestAPI, ParameterSetStrategy_SPS_PPS_LISTING3) {
709+
710+ int iWidth = GetRandWidth();
711+ int iHeight = GetRandHeight();
712+ float fFrameRate = rand() + 0.5f;
713+ int iEncFrameNum = 0;
714+ int iSpatialLayerNum = 1;
715+ int iSliceNum = 1;
716+
717+ // prepare params
718+ SEncParamExt sParam1;
719+ SEncParamExt sParam2;
720+ SEncParamExt sParam3;
721+ encoder_->GetDefaultParams (&sParam1);
722+ prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
723+ sParam1.eSpsPpsIdStrategy = SPS_PPS_LISTING;
724+ //prepare param2
725+ memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
726+ while (GET_MB_WIDTH (sParam2.iPicWidth) == GET_MB_WIDTH (sParam1.iPicWidth)) {
727+ sParam2.iPicWidth = GetRandWidth();
728+ }
729+ prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam2.iPicWidth, sParam2.iPicHeight, fFrameRate, &sParam2);
730+ sParam2.eSpsPpsIdStrategy = SPS_PPS_LISTING;
731+ //prepare param3
732+ memcpy (&sParam3, &sParam1, sizeof (SEncParamExt));
733+ while (GET_MB_WIDTH (sParam3.iPicWidth) == GET_MB_WIDTH (sParam1.iPicWidth) ||
734+ GET_MB_WIDTH (sParam3.iPicWidth) == GET_MB_WIDTH (sParam2.iPicWidth)) {
735+ sParam3.iPicWidth = GetRandWidth();
736+ }
737+ prepareParamDefault (iSpatialLayerNum, iSliceNum, sParam3.iPicWidth, sParam3.iPicHeight, fFrameRate, &sParam3);
738+ sParam3.eSpsPpsIdStrategy = SPS_PPS_LISTING;
739+
740+ //prepare output if needed
741+ FILE* fEnc = NULL;
742+#ifdef DEBUG_FILE_SAVE5
743+ fEnc = fopen ("enc4.264", "wb");
744+#endif
745+
746+ // step#1: ordinary encoding
747+ int rv = encoder_->InitializeExt (&sParam1);
748+ ASSERT_TRUE (rv == cmResultSuccess) << "InitializeExt: rv = " << rv << " at " << sParam1.iPicWidth << "x" <<
749+ sParam1.iPicHeight;
750+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
751+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
752+ EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
753+
754+ // step#2: set strategy for success
755+ int32_t iNewStra = SPS_PPS_LISTING;
756+ rv = encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iNewStra);
757+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv << " iNewStra=" << iNewStra;
758+
759+ // step#3: setting new strategy, SHOULD encounter ERROR
760+ unsigned int TraceLevel = WELS_LOG_QUIET;
761+ rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &TraceLevel);
762+ ASSERT_TRUE (rv == cmResultSuccess);
763+ iNewStra = CONSTANT_ID;
764+ rv = encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iNewStra);
765+ ASSERT_TRUE (rv != cmResultSuccess);
766+
767+ EncDecOneFrame (sParam2.iPicWidth, sParam2.iPicHeight, iEncFrameNum++, fEnc);
768+
769+ // step#4: pParam3, SHOULD encounter ERROR
770+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam3);
771+ ASSERT_TRUE (rv != cmResultSuccess) << "SetOption: rv = " << rv << " at " << sParam3.iPicWidth << "x" <<
772+ sParam3.iPicHeight;
773+
774+ rv = encoder_->Uninitialize();
775+ ASSERT_TRUE (rv == cmResultSuccess) << "rv = " << rv;
776+
777+#ifdef DEBUG_FILE_SAVE5
778+ fclose (fEnc);
779+#endif
780+}
781+
782+
783+TEST_F (EncodeDecodeTestAPI, SimulcastSVC) {
784+ int iSpatialLayerNum = WelsClip3 ((rand() % MAX_SPATIAL_LAYER_NUM), 2, MAX_SPATIAL_LAYER_NUM);
785+ int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 16, MAX_WIDTH);
786+ int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 16, MAX_HEIGHT);
787+ float fFrameRate = rand() + 0.5f;
788+ int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
789+ int iSliceNum = 1;
790+ encoder_->GetDefaultParams (&param_);
791+ prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
792+
793+ int rv = encoder_->InitializeExt (&param_);
794+ ASSERT_TRUE (rv == cmResultSuccess);
795+
796+ unsigned char* pBsBuf[MAX_SPATIAL_LAYER_NUM];
797+ int aLen[MAX_SPATIAL_LAYER_NUM] = {0};
798+ ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
799+
800+#ifdef DEBUG_FILE_SAVE2
801+ FILE* fEnc[MAX_SPATIAL_LAYER_NUM] = { NULL };
802+ fEnc[0] = fopen ("enc0.264", "wb");
803+ fEnc[1] = fopen ("enc1.264", "wb");
804+ fEnc[2] = fopen ("enc2.264", "wb");
805+ fEnc[3] = fopen ("enc3.264", "wb");
806+#endif
807+
808+ // init decoders
809+ int iIdx = 0;
810+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
811+ pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
812+ EXPECT_TRUE (pBsBuf[iIdx] != NULL);
813+ aLen[iIdx] = 0;
814+
815+ long rv = WelsCreateDecoder (&decoder[iIdx]);
816+ ASSERT_EQ (0, rv);
817+ EXPECT_TRUE (decoder[iIdx] != NULL);
818+
819+ SDecodingParam decParam;
820+ memset (&decParam, 0, sizeof (SDecodingParam));
821+ decParam.uiTargetDqLayer = UCHAR_MAX;
822+ decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
823+ decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
824+
825+ rv = decoder[iIdx]->Initialize (&decParam);
826+ ASSERT_EQ (0, rv);
827+ }
828+
829+ for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
830+ int iResult;
831+ int iLayerLen = 0;
832+ unsigned char* pData[3] = { NULL };
833+
834+ InitialEncDec (param_.iPicWidth, param_.iPicHeight);
835+ EncodeOneFrame (0);
836+
837+ iLayerLen = 0;
838+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
839+ aLen[iIdx] = 0;
840+ }
841+ for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
842+ iLayerLen = 0;
843+ const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
844+ for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
845+ iLayerLen += layerInfo.pNalLengthInByte[iNal];
846+ }
847+
848+ if (layerInfo.uiLayerType == NON_VIDEO_CODING_LAYER) {
849+ // under SimulcastSVC, need to copy non-VCL to all layers
850+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
851+ memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
852+ aLen[iIdx] += iLayerLen;
853+ }
854+ } else {
855+ iIdx = layerInfo.uiSpatialId;
856+ EXPECT_TRUE (iIdx < iSpatialLayerNum);
857+ memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
858+ aLen[iIdx] += iLayerLen;
859+ }
860+ }
861+
862+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
863+ pData[0] = pData[1] = pData[2] = 0;
864+ memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
865+
866+#ifdef DEBUG_FILE_SAVE2
867+ fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
868+#endif
869+ iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
870+ EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
871+ iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
872+ EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
873+ EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
874+ }
875+ }
876+
877+ // free all
878+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
879+ if (pBsBuf[iIdx]) {
880+ free (pBsBuf[iIdx]);
881+ }
882+
883+ if (decoder[iIdx] != NULL) {
884+ decoder[iIdx]->Uninitialize();
885+ WelsDestroyDecoder (decoder[iIdx]);
886+ }
887+
888+#ifdef DEBUG_FILE_SAVE2
889+ fclose (fEnc[iIdx]);
890+#endif
891+ }
892+
893+}
894+
895+TEST_F (EncodeDecodeTestAPI, SimulcastAVC) {
896+//#define DEBUG_FILE_SAVE3
897+ int iSpatialLayerNum = WelsClip3 ((rand() % MAX_SPATIAL_LAYER_NUM), 2, MAX_SPATIAL_LAYER_NUM);
898+ int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 16, MAX_WIDTH);
899+ int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 16, MAX_HEIGHT);
900+ float fFrameRate = rand() + 0.5f;
901+ int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
902+ int iSliceNum = 1;
903+ encoder_->GetDefaultParams (&param_);
904+ prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
905+
906+ //set flag of bSimulcastAVC
907+ param_.bSimulcastAVC = true;
908+
909+ int rv = encoder_->InitializeExt (&param_);
910+ ASSERT_TRUE (rv == cmResultSuccess);
911+
912+ unsigned char* pBsBuf[MAX_SPATIAL_LAYER_NUM];
913+ int aLen[MAX_SPATIAL_LAYER_NUM] = {0};
914+ ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
915+
916+#ifdef DEBUG_FILE_SAVE3
917+ FILE* fEnc[MAX_SPATIAL_LAYER_NUM];
918+ fEnc[0] = fopen ("enc0.264", "wb");
919+ fEnc[1] = fopen ("enc1.264", "wb");
920+ fEnc[2] = fopen ("enc2.264", "wb");
921+ fEnc[3] = fopen ("enc3.264", "wb");
922+#endif
923+
924+ int iIdx = 0;
925+
926+ //create decoder
927+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
928+ pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
929+ EXPECT_TRUE (pBsBuf[iIdx] != NULL);
930+ aLen[iIdx] = 0;
931+
932+ long rv = WelsCreateDecoder (&decoder[iIdx]);
933+ ASSERT_EQ (0, rv);
934+ EXPECT_TRUE (decoder[iIdx] != NULL);
935+
936+ SDecodingParam decParam;
937+ memset (&decParam, 0, sizeof (SDecodingParam));
938+ decParam.uiTargetDqLayer = UCHAR_MAX;
939+ decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
940+ decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
941+
942+ rv = decoder[iIdx]->Initialize (&decParam);
943+ ASSERT_EQ (0, rv);
944+ }
945+
946+ iEncFrameNum = 10;
947+ for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
948+ int iResult;
949+ int iLayerLen = 0;
950+ unsigned char* pData[3] = { NULL };
951+
952+ InitialEncDec (param_.iPicWidth, param_.iPicHeight);
953+ EncodeOneFrame (0);
954+
955+ // init
956+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
957+ aLen[iIdx] = 0;
958+ }
959+ for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
960+ iLayerLen = 0;
961+ const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
962+ const int kiFirstNalType = ((* (layerInfo.pBsBuf + 4)) & 0x1f);
963+ ASSERT_TRUE ((kiFirstNalType == NAL_SPS) || (kiFirstNalType == NAL_PPS) || (kiFirstNalType == NAL_SLICE)
964+ || (kiFirstNalType == NAL_SLICE_IDR) || (kiFirstNalType == NAL_SEI));
965+ for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
966+ iLayerLen += layerInfo.pNalLengthInByte[iNal];
967+ }
968+
969+ iIdx = layerInfo.uiSpatialId;
970+ EXPECT_TRUE (iIdx < iSpatialLayerNum);
971+ memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
972+ aLen[iIdx] += iLayerLen;
973+ }
974+
975+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
976+ pData[0] = pData[1] = pData[2] = 0;
977+ memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
978+
979+#ifdef DEBUG_FILE_SAVE3
980+ fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
981+#endif
982+ iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
983+ EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
984+
985+ iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
986+ EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
987+ EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
988+ }
989+ }
990+
991+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
992+ free (pBsBuf[iIdx]);
993+
994+ if (decoder[iIdx] != NULL) {
995+ decoder[iIdx]->Uninitialize();
996+ WelsDestroyDecoder (decoder[iIdx]);
997+ }
998+ }
999+#ifdef DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1000+ for (int i = 0; i <)MAX_SPATIAL_LAYER_NUM;
1001+ i++) {
1002+ fclose (fEnc[i]);
1003+ }
1004+#endif
1005+}
1006+
1007+TEST_F (EncodeDecodeTestAPI, SimulcastAVC_SPS_PPS_LISTING) {
1008+ int iSpatialLayerNum = WelsClip3 ((rand() % MAX_SPATIAL_LAYER_NUM), 2, MAX_SPATIAL_LAYER_NUM);;
1009+ int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
1010+ int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
1011+ float fFrameRate = rand() + 0.5f;
1012+ int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1013+ int iSliceNum = 1;
1014+ iWidth = VALID_SIZE (iWidth);
1015+ iHeight = VALID_SIZE (iHeight);
1016+ // prepare params
1017+ SEncParamExt sParam1;
1018+ SEncParamExt sParam2;
1019+ encoder_->GetDefaultParams (&sParam1);
1020+ prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
1021+ //set flag of SPS_PPS_LISTING
1022+ sParam1.eSpsPpsIdStrategy = SPS_PPS_LISTING;//SPS_LISTING;//
1023+ //set flag of bSimulcastAVC
1024+ sParam1.bSimulcastAVC = true;
1025+ //prepare param2
1026+ memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
1027+ sParam2.sSpatialLayers[0].iVideoWidth = (sParam1.sSpatialLayers[0].iVideoWidth / 2);
1028+ sParam2.sSpatialLayers[0].iVideoHeight = (sParam1.sSpatialLayers[0].iVideoHeight / 2);
1029+
1030+ int rv = encoder_->InitializeExt (&sParam1);
1031+ ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam1: rv = " << rv;;
1032+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
1033+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
1034+
1035+ unsigned char* pBsBuf[MAX_SPATIAL_LAYER_NUM];
1036+ ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1037+
1038+ int iIdx = 0;
1039+
1040+ //create decoder
1041+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1042+ pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1043+ EXPECT_TRUE (pBsBuf[iIdx] != NULL);
1044+
1045+ long rv = WelsCreateDecoder (&decoder[iIdx]);
1046+ ASSERT_EQ (0, rv);
1047+ EXPECT_TRUE (decoder[iIdx] != NULL);
1048+
1049+ SDecodingParam decParam;
1050+ memset (&decParam, 0, sizeof (SDecodingParam));
1051+ decParam.uiTargetDqLayer = UCHAR_MAX;
1052+ decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1053+ decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1054+
1055+ rv = decoder[iIdx]->Initialize (&decParam);
1056+ ASSERT_EQ (0, rv);
1057+ }
1058+
1059+ TestOneSimulcastAVC (&sParam1, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0);
1060+ TestOneSimulcastAVC (&sParam2, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0);
1061+
1062+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1063+ free (pBsBuf[iIdx]);
1064+
1065+ if (decoder[iIdx] != NULL) {
1066+ decoder[iIdx]->Uninitialize();
1067+ WelsDestroyDecoder (decoder[iIdx]);
1068+ }
1069+
1070+ }
1071+}
1072+
1073+struct EncodeOptionParam {
1074+ bool bTestNalSize;
1075+ bool bAllRandom;
1076+ bool bTestDecoder;
1077+ int iNumframes;
1078+ int iWidth;
1079+ int iHeight;
1080+ int iQp;
1081+ SliceModeEnum eSliceMode;
1082+ int uiMaxNalLen;
1083+ float fFramerate;
1084+ int iThreads;
1085+ const char* sFileSave;
1086+};
1087+
1088+static const EncodeOptionParam kOptionParamArray[] = {
1089+ {true, true, false, 30, 600, 460, 1, SM_SIZELIMITED_SLICE, 450, 15.0, 1, ""},
1090+ {true, true, false, 30, 340, 96, 24, SM_SIZELIMITED_SLICE, 1000, 30.0, 1, ""},
1091+ {true, true, false, 30, 140, 196, 51, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1092+ {true, true, false, 30, 110, 296, 50, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1093+ {true, true, false, 30, 104, 416, 44, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1094+ {true, true, false, 30, 16, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1095+ {true, false, true, 30, 600, 460, 1, SM_SIZELIMITED_SLICE, 450, 15.0, 1, ""},
1096+ {true, false, true, 30, 340, 96, 24, SM_SIZELIMITED_SLICE, 1000, 30.0, 1, ""},
1097+ {true, false, true, 30, 140, 196, 51, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1098+ {true, false, true, 30, 110, 296, 50, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1099+ {true, false, true, 30, 104, 416, 44, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1100+ {true, false, true, 30, 16, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1101+ {true, true, true, 30, 600, 460, 1, SM_SIZELIMITED_SLICE, 450, 15.0, 1, ""},
1102+ {true, true, true, 30, 340, 96, 24, SM_SIZELIMITED_SLICE, 1000, 30.0, 1, ""},
1103+ {true, true, true, 30, 140, 196, 51, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1104+ {true, true, true, 30, 110, 296, 50, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1105+ {true, true, true, 30, 104, 416, 44, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1106+ {true, true, true, 30, 16, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1107+ {false, false, true, 3, 4096, 2304, 2, SM_SINGLE_SLICE, 0, 7.5, 1, ""}, // large picture size
1108+ {false, true, false, 30, 32, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 1, ""},
1109+ {false, true, false, 30, 600, 460, 1, SM_SIZELIMITED_SLICE, 450, 15.0, 4, ""},
1110+ {false, true, false, 30, 340, 96, 24, SM_SIZELIMITED_SLICE, 1000, 30.0, 2, ""},
1111+ {false, true, false, 30, 140, 196, 51, SM_SIZELIMITED_SLICE, 500, 7.5, 3, ""},
1112+ {false, true, false, 30, 110, 296, 50, SM_SIZELIMITED_SLICE, 500, 7.5, 2, ""},
1113+ {false, true, false, 30, 104, 416, 44, SM_SIZELIMITED_SLICE, 500, 7.5, 2, ""},
1114+ {false, true, false, 30, 16, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 3, ""},
1115+ {false, true, false, 30, 32, 16, 2, SM_SIZELIMITED_SLICE, 500, 7.5, 3, ""},
1116+ {false, false, true, 30, 600, 460, 1, SM_FIXEDSLCNUM_SLICE, 0, 15.0, 4, ""},
1117+ {false, false, true, 30, 600, 460, 1, SM_FIXEDSLCNUM_SLICE, 0, 15.0, 8, ""},
1118+};
1119+
1120+class EncodeTestAPI : public ::testing::TestWithParam<EncodeOptionParam>, public ::EncodeDecodeTestAPIBase {
1121+ public:
1122+ void SetUp() {
1123+ EncodeDecodeTestAPIBase::SetUp();
1124+ }
1125+
1126+ void TearDown() {
1127+ EncodeDecodeTestAPIBase::TearDown();
1128+ }
1129+ void EncodeOneFrameRandom (int iCheckTypeIndex, bool bAllRandom) {
1130+ int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
1131+ uint8_t* ptr = buf_.data();
1132+ uint8_t uiVal = rand() % 256;
1133+ for (int i = 0; i < frameSize; i++) {
1134+ ptr[i] = bAllRandom ? (rand() % 256) : uiVal;
1135+ }
1136+ int rv = encoder_->EncodeFrame (&EncPic, &info);
1137+ if (0 == iCheckTypeIndex)
1138+ ASSERT_TRUE (rv == cmResultSuccess) << "rv=" << rv;
1139+ else if (1 == iCheckTypeIndex)
1140+ ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnknownReason) << "rv=" << rv;
1141+ }
1142+};
1143+
1144+INSTANTIATE_TEST_CASE_P (EncodeDecodeTestAPIBase, EncodeTestAPI,
1145+ ::testing::ValuesIn (kOptionParamArray));
1146+
1147+TEST_P (EncodeTestAPI, SetEncOptionSize) {
1148+ EncodeOptionParam p = GetParam();
1149+ FILE* pFile = NULL;
1150+ if (p.sFileSave != NULL && strlen (p.sFileSave) > 0) {
1151+ pFile = fopen (p.sFileSave, "wb");
1152+ }
1153+ memset (&param_, 0, sizeof (SEncParamExt));
1154+ encoder_->GetDefaultParams (&param_);
1155+ param_.uiMaxNalSize = p.uiMaxNalLen;
1156+ param_.iTemporalLayerNum = (rand() % 4) + 1;
1157+ param_.iSpatialLayerNum = 1;
1158+ param_.iUsageType = CAMERA_VIDEO_REAL_TIME;
1159+ param_.iPicWidth = p.iWidth;
1160+ param_.iPicHeight = p.iHeight;
1161+ param_.fMaxFrameRate = p.fFramerate;
1162+ param_.iRCMode = RC_OFF_MODE; //rc off
1163+ param_.iMultipleThreadIdc = p.iThreads;
1164+ param_.iNumRefFrame = AUTO_REF_PIC_COUNT;
1165+ param_.sSpatialLayers[0].iVideoWidth = p.iWidth ;
1166+ param_.sSpatialLayers[0].iVideoHeight = p.iHeight;
1167+ param_.sSpatialLayers[0].fFrameRate = p.fFramerate;
1168+ param_.sSpatialLayers[0].sSliceArgument.uiSliceMode = p.eSliceMode;
1169+ if (SM_FIXEDSLCNUM_SLICE == p.eSliceMode) {
1170+ param_.sSpatialLayers[0].sSliceArgument.uiSliceNum = 8;
1171+ }
1172+
1173+ encoder_->Uninitialize();
1174+ int rv = encoder_->InitializeExt (&param_);
1175+ ASSERT_TRUE (rv == cmResultSuccess);
1176+ InitialEncDec (p.iWidth, p.iHeight);
1177+
1178+ int32_t iTraceLevel = WELS_LOG_QUIET;
1179+ encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1180+ decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1181+ int32_t iSpsPpsIdAddition = 1;
1182+ encoder_->SetOption (ENCODER_OPTION_ENABLE_SPS_PPS_ID_ADDITION, &iSpsPpsIdAddition);
1183+ int32_t iIDRPeriod = (int32_t) pow (2.0f, (param_.iTemporalLayerNum - 1)) * ((rand() % 5) + 1);
1184+ encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
1185+ int iIdx = 0;
1186+ int iLen;
1187+ unsigned char* pData[3] = { NULL };
1188+
1189+ //FIXME: remove this after the multi-thread case is correctly handled in encoder
1190+ if (p.iThreads > 1 && SM_SIZELIMITED_SLICE == p.eSliceMode) {
1191+ p.bAllRandom = false;
1192+ }
1193+
1194+ while (iIdx <= p.iNumframes) {
1195+ EncodeOneFrameRandom (0, p.bAllRandom);
1196+ encToDecData (info, iLen);
1197+ if (pFile) {
1198+ fwrite (info.sLayerInfo[0].pBsBuf, iLen, 1, pFile);
1199+ fflush (pFile);
1200+ }
1201+ memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
1202+ if (iLen && p.bTestDecoder) {
1203+ rv = decoder_->DecodeFrameNoDelay (info.sLayerInfo[0].pBsBuf, iLen, pData, &dstBufInfo_);
1204+ ASSERT_EQ (rv, 0);
1205+ ASSERT_EQ (dstBufInfo_.iBufferStatus, 1);
1206+ }
1207+ int iLayer = 0;
1208+ while (iLayer < info.iLayerNum) {
1209+ SLayerBSInfo* pLayerBsInfo = &info.sLayerInfo[iLayer];
1210+ if (pLayerBsInfo != NULL) {
1211+ int iNalIdx = WELS_MAX (pLayerBsInfo->iNalCount - 2, 0); // ignore last slice under single slice mode
1212+ do {
1213+ if (p.bTestNalSize) { // ignore the case that 2 MBs in one picture, and the multithreads case, enable them when code is ready
1214+ ASSERT_GE (((int)param_.uiMaxNalSize), pLayerBsInfo->pNalLengthInByte[iNalIdx]);
1215+ }
1216+ -- iNalIdx;
1217+ } while (iNalIdx >= 0);
1218+ }
1219+ ++ iLayer;
1220+ }
1221+ iIdx++;
1222+ }
1223+ if (pFile) {
1224+ fclose (pFile);
1225+ }
1226+}
1227+
1228+
1229+
1230+TEST_F (EncodeDecodeTestAPI, SimulcastAVCDiffFps) {
1231+//#define DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1232+ int iSpatialLayerNum = WelsClip3 ((rand() % MAX_SPATIAL_LAYER_NUM), 2, MAX_SPATIAL_LAYER_NUM);
1233+ int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
1234+ int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
1235+ float fFrameRate = 30;
1236+ int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1237+ int iSliceNum = 1;
1238+ encoder_->GetDefaultParams (&param_);
1239+ prepareParam (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &param_);
1240+
1241+ //set flag of bSimulcastAVC
1242+ param_.bSimulcastAVC = true;
1243+ param_.iTemporalLayerNum = (rand() % 2) ? 3 : 4;
1244+
1245+ unsigned char* pBsBuf[MAX_SPATIAL_LAYER_NUM];
1246+ int aLen[MAX_SPATIAL_LAYER_NUM] = {0};
1247+ ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1248+
1249+#ifdef DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1250+ FILE* fEnc[MAX_SPATIAL_LAYER_NUM];
1251+ fEnc[0] = fopen ("enc0.264", "wb");
1252+ fEnc[1] = fopen ("enc1.264", "wb");
1253+ fEnc[2] = fopen ("enc2.264", "wb");
1254+ fEnc[3] = fopen ("enc3.264", "wb");
1255+#endif
1256+
1257+ int iIdx = 0;
1258+
1259+ //create decoder
1260+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1261+ pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1262+ EXPECT_TRUE (pBsBuf[iIdx] != NULL);
1263+ aLen[iIdx] = 0;
1264+
1265+ long rv = WelsCreateDecoder (&decoder[iIdx]);
1266+ ASSERT_EQ (0, rv);
1267+ EXPECT_TRUE (decoder[iIdx] != NULL);
1268+
1269+ SDecodingParam decParam;
1270+ memset (&decParam, 0, sizeof (SDecodingParam));
1271+ decParam.uiTargetDqLayer = UCHAR_MAX;
1272+ decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1273+ decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1274+
1275+ rv = decoder[iIdx]->Initialize (&decParam);
1276+ ASSERT_EQ (0, rv);
1277+ }
1278+
1279+#define PATTERN_NUM (18)
1280+ 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},
1281+ {1, 2, 1, 1}, {1, 1, 2, 1}, {1, 4, 1, 1}, {2, 4, 2, 1}, {1, 4, 2, 1}, {1, 4, 4, 1},
1282+ {1, 2, 2, 1}, {2, 1, 2, 1}, {1, 2, 4, 1},
1283+ {1, 1, 1, 2}, {1, 2, 2, 2}, {1, 2, 2, 4}, {1, 2, 4, 2}, {1, 4, 4, 4},
1284+ };
1285+ for (int iPatternIdx = 0; iPatternIdx < PATTERN_NUM; iPatternIdx++) {
1286+ for (int i = 0; i < iSpatialLayerNum; i++) {
1287+ param_.sSpatialLayers[i].fFrameRate = (fFrameRate / iTemporalPattern[iPatternIdx][i]);
1288+ }
1289+
1290+ int rv = encoder_->InitializeExt (&param_);
1291+ ASSERT_TRUE (rv == cmResultSuccess);
1292+
1293+ iEncFrameNum = 10;
1294+ int iInsertIdr = rand() % iEncFrameNum;
1295+ for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
1296+ int iResult;
1297+ int iLayerLen = 0;
1298+ unsigned char* pData[3] = { NULL };
1299+
1300+ InitialEncDec (param_.iPicWidth, param_.iPicHeight);
1301+ EncodeOneFrame (0);
1302+
1303+ if (iInsertIdr == iFrame) {
1304+ encoder_->ForceIntraFrame (true);
1305+ }
1306+
1307+ // init aLen for the current frame
1308+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1309+ aLen[iIdx] = 0;
1310+ }
1311+ for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
1312+ iLayerLen = 0;
1313+ const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
1314+ const int kiFirstNalType = ((* (layerInfo.pBsBuf + 4)) & 0x1f);
1315+ ASSERT_TRUE ((kiFirstNalType == NAL_SPS) || (kiFirstNalType == NAL_PPS) || (kiFirstNalType == NAL_SLICE)
1316+ || (kiFirstNalType == NAL_SLICE_IDR) || (kiFirstNalType == NAL_SEI));
1317+ for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
1318+ iLayerLen += layerInfo.pNalLengthInByte[iNal];
1319+ }
1320+
1321+ iIdx = layerInfo.uiSpatialId;
1322+ EXPECT_TRUE (iIdx < iSpatialLayerNum);
1323+ memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
1324+ aLen[iIdx] += iLayerLen;
1325+ }
1326+
1327+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1328+ pData[0] = pData[1] = pData[2] = 0;
1329+ memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
1330+
1331+ if (aLen[iIdx] > 0) {
1332+#ifdef DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1333+ fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
1334+#endif
1335+ iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
1336+ EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
1337+
1338+ iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
1339+ EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx << iPatternIdx;
1340+ EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
1341+ }
1342+ }
1343+ }
1344+ }
1345+
1346+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1347+ free (pBsBuf[iIdx]);
1348+
1349+ if (decoder[iIdx] != NULL) {
1350+ decoder[iIdx]->Uninitialize();
1351+ WelsDestroyDecoder (decoder[iIdx]);
1352+ }
1353+ }
1354+#ifdef DEBUG_FILE_SAVE_SimulcastAVCDiffFps
1355+ for (int i = 0; i < MAX_SPATIAL_LAYER_NUM; i++) {
1356+ fclose (fEnc[i]);
1357+ }
1358+#endif
1359+}
1360+
1361+TEST_F (EncodeDecodeTestAPI, DiffSlicingInDlayer) {
1362+ int iSpatialLayerNum = 3;
1363+ int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, (64 << 2), MAX_WIDTH);
1364+ int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, (64 << 2),
1365+ 2240);//TODO: use MAX_HEIGHT after the limit is removed
1366+ float fFrameRate = rand() + 0.5f;
1367+ int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1368+
1369+ // prepare params
1370+ SEncParamExt sParam;
1371+ encoder_->GetDefaultParams (&sParam);
1372+ prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1373+ sParam.iMultipleThreadIdc = (rand() % 4) + 1;
1374+ sParam.bSimulcastAVC = 1;
1375+ sParam.sSpatialLayers[0].iVideoWidth = (iWidth >> 2);
1376+ sParam.sSpatialLayers[0].iVideoHeight = (iHeight >> 2);
1377+ sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = SM_RASTER_SLICE;
1378+ sParam.sSpatialLayers[1].sSliceArgument.uiSliceMbNum[0] = 0;
1379+
1380+ sParam.sSpatialLayers[1].iVideoWidth = (iWidth >> 1);
1381+ sParam.sSpatialLayers[1].iVideoHeight = (iHeight >> 1);
1382+ sParam.sSpatialLayers[1].sSliceArgument.uiSliceMode = SM_RASTER_SLICE;
1383+ sParam.sSpatialLayers[1].sSliceArgument.uiSliceMbNum[0] = 30;
1384+ sParam.sSpatialLayers[1].sSliceArgument.uiSliceMbNum[1] = 32;
1385+
1386+ sParam.sSpatialLayers[2].iVideoWidth = iWidth;
1387+ sParam.sSpatialLayers[2].iVideoHeight = iHeight;
1388+ sParam.sSpatialLayers[2].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
1389+ sParam.sSpatialLayers[2].sSliceArgument.uiSliceNum = (rand() % 30) + 1;
1390+
1391+ int rv = encoder_->InitializeExt (&sParam);
1392+ ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1393+
1394+ unsigned char* pBsBuf[MAX_SPATIAL_LAYER_NUM];
1395+ ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1396+
1397+ int iIdx = 0;
1398+
1399+ //create decoder
1400+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1401+ pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1402+ EXPECT_TRUE (pBsBuf[iIdx] != NULL);
1403+
1404+ long rv = WelsCreateDecoder (&decoder[iIdx]);
1405+ ASSERT_EQ (0, rv);
1406+ EXPECT_TRUE (decoder[iIdx] != NULL);
1407+
1408+ SDecodingParam decParam;
1409+ memset (&decParam, 0, sizeof (SDecodingParam));
1410+ decParam.uiTargetDqLayer = UCHAR_MAX;
1411+ decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1412+ decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1413+
1414+ rv = decoder[iIdx]->Initialize (&decParam);
1415+ ASSERT_EQ (0, rv);
1416+ }
1417+
1418+ TestOneSimulcastAVC (&sParam, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0);
1419+
1420+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1421+ free (pBsBuf[iIdx]);
1422+
1423+ if (decoder[iIdx] != NULL) {
1424+ decoder[iIdx]->Uninitialize();
1425+ WelsDestroyDecoder (decoder[iIdx]);
1426+ }
1427+
1428+ }
1429+}
1430+
1431+TEST_F (EncodeDecodeTestAPI, DiffSlicingInDlayerMixed) {
1432+ int iSpatialLayerNum = 2;
1433+ int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, (64 << 2), MAX_WIDTH);
1434+ int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, (64 << 2),
1435+ 1120);//TODO: use MAX_HEIGHT after the limit is removed
1436+ float fFrameRate = rand() + 0.5f;
1437+ int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1438+
1439+ // prepare params
1440+ SEncParamExt sParam;
1441+ encoder_->GetDefaultParams (&sParam);
1442+ prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1443+ sParam.iMultipleThreadIdc = (rand() % 4) + 1;
1444+ sParam.bSimulcastAVC = 1;
1445+ sParam.sSpatialLayers[0].iVideoWidth = (iWidth >> 2);
1446+ sParam.sSpatialLayers[0].iVideoHeight = (iHeight >> 2);
1447+ sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = SM_RASTER_SLICE;
1448+
1449+ sParam.sSpatialLayers[1].iVideoWidth = iWidth;
1450+ sParam.sSpatialLayers[1].iVideoHeight = iHeight;
1451+ sParam.sSpatialLayers[1].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
1452+ sParam.sSpatialLayers[1].sSliceArgument.uiSliceNum = 1;
1453+
1454+ int rv = encoder_->InitializeExt (&sParam);
1455+ ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1456+
1457+ unsigned char* pBsBuf[MAX_SPATIAL_LAYER_NUM];
1458+ ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1459+
1460+ int iIdx = 0;
1461+
1462+ //create decoder
1463+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1464+ pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1465+ EXPECT_TRUE (pBsBuf[iIdx] != NULL);
1466+
1467+ long rv = WelsCreateDecoder (&decoder[iIdx]);
1468+ ASSERT_EQ (0, rv);
1469+ EXPECT_TRUE (decoder[iIdx] != NULL);
1470+
1471+ SDecodingParam decParam;
1472+ memset (&decParam, 0, sizeof (SDecodingParam));
1473+ decParam.uiTargetDqLayer = UCHAR_MAX;
1474+ decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1475+ decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1476+
1477+ rv = decoder[iIdx]->Initialize (&decParam);
1478+ ASSERT_EQ (0, rv);
1479+ }
1480+
1481+ TestOneSimulcastAVC (&sParam, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0);
1482+
1483+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1484+ free (pBsBuf[iIdx]);
1485+
1486+ if (decoder[iIdx] != NULL) {
1487+ decoder[iIdx]->Uninitialize();
1488+ WelsDestroyDecoder (decoder[iIdx]);
1489+ }
1490+
1491+ }
1492+}
1493+
1494+TEST_F (EncodeDecodeTestAPI, ThreadNumAndSliceNum) {
1495+ int iSpatialLayerNum = 1;
1496+ int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, (64 << 2), MAX_WIDTH);
1497+ int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, (64 << 2),
1498+ 2240);//TODO: use MAX_HEIGHT after the limit is removed
1499+ float fFrameRate = rand() + 0.5f;
1500+ int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1501+
1502+ // prepare params
1503+ SEncParamExt sParam;
1504+ encoder_->GetDefaultParams (&sParam);
1505+ prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1506+ sParam.iMultipleThreadIdc = (rand() % 3) + 2;
1507+ sParam.bSimulcastAVC = 1;
1508+ sParam.sSpatialLayers[0].iVideoWidth = iWidth;
1509+ sParam.sSpatialLayers[0].iVideoHeight = iHeight;
1510+ sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
1511+ sParam.sSpatialLayers[0].sSliceArgument.uiSliceNum = (rand() % 2) ? (sParam.iMultipleThreadIdc + 1) :
1512+ (sParam.iMultipleThreadIdc - 1);
1513+
1514+ int rv = encoder_->InitializeExt (&sParam);
1515+ ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1516+
1517+ unsigned char* pBsBuf[MAX_SPATIAL_LAYER_NUM];
1518+ ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1519+
1520+ int iIdx = 0;
1521+
1522+ //create decoder
1523+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1524+ pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1525+ EXPECT_TRUE (pBsBuf[iIdx] != NULL);
1526+
1527+ long rv = WelsCreateDecoder (&decoder[iIdx]);
1528+ ASSERT_EQ (0, rv);
1529+ EXPECT_TRUE (decoder[iIdx] != NULL);
1530+
1531+ SDecodingParam decParam;
1532+ memset (&decParam, 0, sizeof (SDecodingParam));
1533+ decParam.uiTargetDqLayer = UCHAR_MAX;
1534+ decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1535+ decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1536+
1537+ rv = decoder[iIdx]->Initialize (&decParam);
1538+ ASSERT_EQ (0, rv);
1539+ }
1540+
1541+ TestOneSimulcastAVC (&sParam, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0);
1542+
1543+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1544+ free (pBsBuf[iIdx]);
1545+
1546+ if (decoder[iIdx] != NULL) {
1547+ decoder[iIdx]->Uninitialize();
1548+ WelsDestroyDecoder (decoder[iIdx]);
1549+ }
1550+
1551+ }
1552+}
1553+
1554+
1555+TEST_F (EncodeDecodeTestAPI, TriggerLoadBalancing) {
1556+ int iSpatialLayerNum = 1;
1557+ int iWidth = WelsClip3 ((((rand() % MAX_WIDTH) >> 1) + 1) << 1, (64 << 2), MAX_WIDTH);
1558+ int iHeight = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1) + 1) << 1, (64 << 2),
1559+ 2240);//TODO: use MAX_HEIGHT after the limit is removed
1560+ float fFrameRate = rand() + 0.5f;
1561+ int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
1562+
1563+ // prepare params
1564+ SEncParamExt sParam;
1565+ encoder_->GetDefaultParams (&sParam);
1566+ prepareParamDefault (iSpatialLayerNum, 1, iWidth, iHeight, fFrameRate, &sParam);
1567+ sParam.iMultipleThreadIdc = (rand() % 8) + 1;
1568+ sParam.bSimulcastAVC = 1;
1569+ sParam.sSpatialLayers[0].iVideoWidth = iWidth;
1570+ sParam.sSpatialLayers[0].iVideoHeight = iHeight;
1571+ sParam.sSpatialLayers[0].sSliceArgument.uiSliceMode = SM_FIXEDSLCNUM_SLICE;
1572+ sParam.sSpatialLayers[0].sSliceArgument.uiSliceNum = sParam.iMultipleThreadIdc;
1573+
1574+ int rv = encoder_->InitializeExt (&sParam);
1575+ ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam: rv = " << rv;;
1576+
1577+ unsigned char* pBsBuf[MAX_SPATIAL_LAYER_NUM];
1578+ ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
1579+
1580+ int iIdx = 0;
1581+ int aLen[MAX_SPATIAL_LAYER_NUM] = {};
1582+
1583+ //create decoder
1584+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1585+ pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
1586+ EXPECT_TRUE (pBsBuf[iIdx] != NULL);
1587+
1588+ long rv = WelsCreateDecoder (&decoder[iIdx]);
1589+ ASSERT_EQ (0, rv);
1590+ EXPECT_TRUE (decoder[iIdx] != NULL);
1591+
1592+ SDecodingParam decParam;
1593+ memset (&decParam, 0, sizeof (SDecodingParam));
1594+ decParam.uiTargetDqLayer = UCHAR_MAX;
1595+ decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
1596+ decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1597+
1598+ rv = decoder[iIdx]->Initialize (&decParam);
1599+ ASSERT_EQ (0, rv);
1600+ }
1601+
1602+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam);
1603+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed pParam: rv = " << rv;
1604+
1605+ //begin testing
1606+ for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
1607+ int iResult;
1608+ int iLayerLen = 0;
1609+ unsigned char* pData[3] = { NULL };
1610+
1611+ InitialEncDec (sParam.iPicWidth, sParam.iPicHeight);
1612+ int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
1613+ memset (buf_.data(), rand() % 256, (frameSize >> 2));
1614+ memset (buf_.data() + (frameSize >> 2), rand() % 256, (frameSize - (frameSize >> 2)));
1615+
1616+ int iStartStrip = 0;
1617+ //during first half the complex strip is at top, then during the second half it is at bottom
1618+ if (iFrame > iEncFrameNum / 2) {
1619+ iStartStrip = EncPic.iPicHeight * EncPic.iPicWidth;
1620+ }
1621+ for (int k = 0; k < (EncPic.iPicHeight / 2); k++) {
1622+ memset (buf_.data() + k * EncPic.iPicWidth + iStartStrip, rand() % 256, (EncPic.iPicWidth));
1623+ }
1624+
1625+ int rv = encoder_->EncodeFrame (&EncPic, &info);
1626+ ASSERT_TRUE (rv == cmResultSuccess);
1627+
1628+ // init
1629+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1630+ aLen[iIdx] = 0;
1631+ }
1632+ for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
1633+ iLayerLen = 0;
1634+ const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
1635+ for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
1636+ iLayerLen += layerInfo.pNalLengthInByte[iNal];
1637+ }
1638+
1639+ iIdx = layerInfo.uiSpatialId;
1640+ EXPECT_TRUE (iIdx < iSpatialLayerNum) << "iIdx = " << iIdx << ", iSpatialLayerNum = " << iSpatialLayerNum;
1641+ memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
1642+ aLen[iIdx] += iLayerLen;
1643+ }
1644+
1645+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1646+ pData[0] = pData[1] = pData[2] = 0;
1647+ memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
1648+
1649+#ifdef DEBUG_FILE_SAVE4
1650+ fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
1651+#endif
1652+ iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
1653+ EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << ", LayerIdx=" << iIdx;
1654+
1655+ iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
1656+ EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << ", LayerIdx=" << iIdx;
1657+ EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
1658+ }
1659+ }
1660+
1661+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
1662+ free (pBsBuf[iIdx]);
1663+
1664+ if (decoder[iIdx] != NULL) {
1665+ decoder[iIdx]->Uninitialize();
1666+ WelsDestroyDecoder (decoder[iIdx]);
1667+ }
1668+
1669+ }
1670+}
1671+

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t