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 "utils/HashFunctions.h"
9 #include <string>
10 #include <vector>
11 #include "encode_decode_api_test.h"
12 using namespace WelsCommon;
13
TestOutPutTrace(void * ctx,int level,const char * string)14 static void TestOutPutTrace (void* ctx, int level, const char* string) {
15 STraceUnit* pTraceUnit = (STraceUnit*) ctx;
16 EXPECT_LE (level, pTraceUnit->iTarLevel);
17 }
18
TEST_P(EncodeDecodeTestAPI,DecoderVclNal)19 TEST_P (EncodeDecodeTestAPI, DecoderVclNal) {
20 EncodeDecodeFileParamBase p = GetParam();
21 prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
22 encoder_->Uninitialize();
23 int rv = encoder_->InitializeExt (¶m_);
24 ASSERT_TRUE (rv == cmResultSuccess);
25
26 int32_t iTraceLevel = WELS_LOG_QUIET;
27 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
28 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
29
30 ASSERT_TRUE (InitialEncDec (p.width, p.height));
31
32 int iIdx = 0;
33 while (iIdx <= p.numframes) {
34
35 EncodeOneFrame (0);
36
37 //decoding after each encoding frame
38 int vclNal, len = 0;
39 encToDecData (info, len);
40 unsigned char* pData[3] = { NULL };
41 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
42 rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
43 ASSERT_TRUE (rv == cmResultSuccess);
44 rv = decoder_->GetOption (DECODER_OPTION_VCL_NAL, &vclNal);
45 EXPECT_EQ (vclNal, FEEDBACK_UNKNOWN_NAL); //no reconstruction, unknown return
46 rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
47 ASSERT_TRUE (rv == cmResultSuccess);
48 rv = decoder_->GetOption (DECODER_OPTION_VCL_NAL, &vclNal);
49 EXPECT_EQ (vclNal, FEEDBACK_VCL_NAL);
50 iIdx++;
51 } //while
52 //ignore last frame
53 }
54
TEST_P(EncodeDecodeTestAPI,GetOptionFramenum)55 TEST_P (EncodeDecodeTestAPI, GetOptionFramenum) {
56 EncodeDecodeFileParamBase p = GetParam();
57 prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
58 encoder_->Uninitialize();
59 int rv = encoder_->InitializeExt (¶m_);
60 ASSERT_TRUE (rv == cmResultSuccess);
61
62 int32_t iTraceLevel = WELS_LOG_QUIET;
63 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
64 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
65
66 ASSERT_TRUE (InitialEncDec (p.width, p.height));
67
68 int32_t iEncFrameNum = -1;
69 int32_t iDecFrameNum;
70 int iIdx = 0;
71 while (iIdx <= p.numframes) {
72 EncodeOneFrame (0);
73 //decoding after each encoding frame
74 int len = 0;
75 encToDecData (info, len);
76 unsigned char* pData[3] = { NULL };
77 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
78 rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
79 ASSERT_TRUE (rv == cmResultSuccess);
80 decoder_->GetOption (DECODER_OPTION_FRAME_NUM, &iDecFrameNum);
81 EXPECT_EQ (iDecFrameNum, -1);
82 iEncFrameNum++;
83 rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
84 ASSERT_TRUE (rv == cmResultSuccess);
85 decoder_->GetOption (DECODER_OPTION_FRAME_NUM, &iDecFrameNum);
86 EXPECT_EQ (iEncFrameNum, iDecFrameNum);
87 iIdx++;
88 } //while
89 //ignore last frame
90 }
91
TEST_P(EncodeDecodeTestAPI,GetOptionIDR)92 TEST_P (EncodeDecodeTestAPI, GetOptionIDR) {
93 EncodeDecodeFileParamBase p = GetParam();
94 prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
95 encoder_->Uninitialize();
96 int rv = encoder_->InitializeExt (¶m_);
97 ASSERT_TRUE (rv == cmResultSuccess);
98
99 //init for encoder
100 // I420: 1(Y) + 1/4(U) + 1/4(V)
101 int32_t iTraceLevel = WELS_LOG_QUIET;
102 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
103 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
104
105 ASSERT_TRUE (InitialEncDec (p.width, p.height));
106
107 int32_t iEncCurIdrPicId = 0;
108 int32_t iDecCurIdrPicId;
109 int32_t iIDRPeriod = 1;
110 int32_t iSpsPpsIdAddition = 0;
111 int iIdx = 0;
112 while (iIdx <= p.numframes) {
113 iSpsPpsIdAddition = rand() %
114 2; //the current strategy supports more than 2 modes, but the switch between the modes>2 is not allowed
115 iIDRPeriod = (rand() % 150) + 1;
116 encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
117 encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
118
119 EncodeOneFrame (0);
120
121 if (info.eFrameType == videoFrameTypeIDR) {
122 iEncCurIdrPicId = iEncCurIdrPicId + 1;
123 }
124 //decoding after each encoding frame
125 int len = 0;
126 encToDecData (info, len);
127 unsigned char* pData[3] = { NULL };
128 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
129 rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
130 ASSERT_TRUE (rv == cmResultSuccess);
131 decoder_->GetOption (DECODER_OPTION_IDR_PIC_ID, &iDecCurIdrPicId);
132 EXPECT_EQ (iDecCurIdrPicId, iEncCurIdrPicId);
133 rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
134 ASSERT_TRUE (rv == cmResultSuccess);
135 decoder_->GetOption (DECODER_OPTION_IDR_PIC_ID, &iDecCurIdrPicId);
136 EXPECT_EQ (iDecCurIdrPicId, iEncCurIdrPicId);
137 iIdx++;
138 } //while
139 //ignore last frame
140 }
141
TEST_P(EncodeDecodeTestAPI,InOutTimeStamp)142 TEST_P (EncodeDecodeTestAPI, InOutTimeStamp) {
143 EncodeDecodeFileParamBase p = GetParam();
144 prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
145 encoder_->Uninitialize();
146 int rv = encoder_->InitializeExt (¶m_);
147 ASSERT_TRUE (rv == cmResultSuccess);
148
149 ASSERT_TRUE (InitialEncDec (p.width, p.height));
150 int32_t iTraceLevel = WELS_LOG_QUIET;
151 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
152 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
153 int32_t iSpsPpsIdAddition = 1;
154 encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
155 int32_t iIDRPeriod = 60;
156 encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
157 SLTRConfig sLtrConfigVal;
158 sLtrConfigVal.bEnableLongTermReference = 1;
159 sLtrConfigVal.iLTRRefNum = 1;
160 encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
161 int32_t iLtrPeriod = 2;
162 encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
163 int iIdx = 0;
164 int iSkipedBytes;
165 unsigned long long uiEncTimeStamp = 100;
166 while (iIdx <= p.numframes) {
167 EncodeOneFrame (1);
168 //decoding after each encoding frame
169 int len = 0;
170 encToDecData (info, len);
171 unsigned char* pData[3] = { NULL };
172 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
173 uint32_t uiEcIdc = ERROR_CON_SLICE_COPY_CROSS_IDR_FREEZE_RES_CHANGE;
174 decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
175 dstBufInfo_.uiInBsTimeStamp = uiEncTimeStamp;
176 rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
177 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
178 dstBufInfo_.uiInBsTimeStamp = uiEncTimeStamp;
179 rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
180 if (dstBufInfo_.iBufferStatus == 1) {
181 EXPECT_EQ (uiEncTimeStamp, dstBufInfo_.uiOutYuvTimeStamp);
182 }
183 iIdx++;
184 uiEncTimeStamp++;
185 }
186 (void) iSkipedBytes;
187 }
188
TEST_P(EncodeDecodeTestAPI,GetOptionIsRefPic)189 TEST_P (EncodeDecodeTestAPI, GetOptionIsRefPic) {
190 EncodeDecodeFileParamBase p = GetParam();
191 prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
192 encoder_->Uninitialize();
193 int rv = encoder_->InitializeExt (¶m_);
194 ASSERT_TRUE (rv == cmResultSuccess);
195
196 ASSERT_TRUE (InitialEncDec (p.width, p.height));
197 int32_t iTraceLevel = WELS_LOG_QUIET;
198 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
199 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
200 int iIdx = 0;
201 int iSkipedBytes;
202 int iIsRefPic;
203 decoder_->GetOption (DECODER_OPTION_IS_REF_PIC, &iIsRefPic);
204 ASSERT_EQ (iIsRefPic, -1);
205
206 while (iIdx <= p.numframes) {
207 EncodeOneFrame (1);
208 //decoding after each encoding frame
209 int len = 0;
210 encToDecData (info, len);
211 unsigned char* pData[3] = { NULL };
212 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
213 rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
214 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
215 decoder_->GetOption (DECODER_OPTION_IS_REF_PIC, &iIsRefPic);
216 ASSERT_EQ (iIsRefPic, -1);
217 rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
218 if (dstBufInfo_.iBufferStatus == 1) {
219 decoder_->GetOption (DECODER_OPTION_IS_REF_PIC, &iIsRefPic);
220 ASSERT_TRUE (iIsRefPic >= 0);
221 }
222 iIdx++;
223 }
224 (void)iSkipedBytes;
225 }
226
TEST_P(EncodeDecodeTestAPI,GetOptionTid_AVC_NOPREFIX)227 TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_NOPREFIX) {
228 SLTRMarkingFeedback m_LTR_Marking_Feedback;
229 SLTRRecoverRequest m_LTR_Recover_Request;
230 m_LTR_Recover_Request.uiIDRPicId = 0;
231 m_LTR_Recover_Request.iLayerId = 0;
232 m_LTR_Marking_Feedback.iLayerId = 0;
233 EncodeDecodeFileParamBase p = GetParam();
234 prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
235 param_.bPrefixNalAddingCtrl = false;
236 param_.iTemporalLayerNum = (rand() % 4) + 1;
237 encoder_->Uninitialize();
238 int rv = encoder_->InitializeExt (¶m_);
239 ASSERT_TRUE (rv == cmResultSuccess);
240 m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
241 ASSERT_TRUE (InitialEncDec (p.width, p.height));
242 int32_t iTraceLevel = WELS_LOG_QUIET;
243 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
244 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
245 int32_t iSpsPpsIdAddition = 1;
246 encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
247 int32_t iIDRPeriod = 60;
248 encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
249 SLTRConfig sLtrConfigVal;
250 sLtrConfigVal.bEnableLongTermReference = 1;
251 sLtrConfigVal.iLTRRefNum = 1;
252 encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
253 int32_t iLtrPeriod = 2;
254 encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
255 int iIdx = 0;
256 int iLossIdx = 0;
257 bool bVCLLoss = false;
258 while (iIdx <= p.numframes) {
259 EncodeOneFrame (1);
260 if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
261 ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
262 }
263 //decoding after each encoding frame
264 int len = 0;
265 encToDecData (info, len);
266 unsigned char* pData[3] = { NULL };
267 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
268 SimulateNALLoss (info.sLayerInfo[0].pBsBuf, len, &m_SLostSim, p.pLossSequence, p.bLostPara, iLossIdx, bVCLLoss);
269 rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
270 int iTid = -1;
271 decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
272 if (iTid != -1) {
273 ASSERT_EQ (iTid, 0);
274 }
275 m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
276 LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
277 rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
278 decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
279 std::vector<SLostSim>::iterator iter = m_SLostSim.begin();
280 bool bHasVCL = false;
281 for (unsigned int k = 0; k < m_SLostSim.size(); k++) {
282 if (IS_VCL_NAL (iter->eNalType, 0) && iter->isLost == false) {
283 bHasVCL = true;
284 break;
285 }
286 iter++;
287 }
288 (void) bHasVCL;
289 if (iTid != -1) {
290 ASSERT_EQ (iTid, 0);
291 }
292 LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
293 LTRMarkFeedback (decoder_, encoder_, &m_LTR_Marking_Feedback, rv);
294 iIdx++;
295 }
296 }
297
TEST_P(EncodeDecodeTestAPI,GetOptionTid_AVC_WITH_PREFIX_NOLOSS)298 TEST_P (EncodeDecodeTestAPI, GetOptionTid_AVC_WITH_PREFIX_NOLOSS) {
299 SLTRMarkingFeedback m_LTR_Marking_Feedback;
300 SLTRRecoverRequest m_LTR_Recover_Request;
301 m_LTR_Recover_Request.uiIDRPicId = 0;
302 m_LTR_Recover_Request.iLayerId = 0;
303 m_LTR_Marking_Feedback.iLayerId = 0;
304 EncodeDecodeFileParamBase p = GetParam();
305 prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
306 param_.bPrefixNalAddingCtrl = true;
307 param_.iTemporalLayerNum = (rand() % 4) + 1;
308 param_.iSpatialLayerNum = 1;
309 encoder_->Uninitialize();
310 int rv = encoder_->InitializeExt (¶m_);
311 ASSERT_TRUE (rv == cmResultSuccess);
312 m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
313
314 ASSERT_TRUE (InitialEncDec (p.width, p.height));
315 int32_t iTraceLevel = WELS_LOG_QUIET;
316 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
317 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
318 int32_t iSpsPpsIdAddition = 1;
319 encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
320 int32_t iIDRPeriod = 60;
321 encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
322 SLTRConfig sLtrConfigVal;
323 sLtrConfigVal.bEnableLongTermReference = 1;
324 sLtrConfigVal.iLTRRefNum = 1;
325 encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
326 int32_t iLtrPeriod = 2;
327 encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
328 int iIdx = 0;
329 while (iIdx <= p.numframes) {
330 EncodeOneFrame (1);
331 if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
332 ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
333 }
334 //decoding after each encoding frame
335 int len = 0;
336 encToDecData (info, len);
337 unsigned char* pData[3] = { NULL };
338 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
339 ExtractDidNal (&info, len, &m_SLostSim, 0);
340 rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
341 int iTid = -1;
342 decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
343 ASSERT_EQ (iTid, -1);
344 m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
345 LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
346 rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
347 decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
348 ASSERT_EQ (iTid, info.sLayerInfo[0].uiTemporalId);
349 LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
350 LTRMarkFeedback (decoder_, encoder_, &m_LTR_Marking_Feedback, rv);
351 iIdx++;
352 }
353 }
354
TEST_P(EncodeDecodeTestAPI,GetOptionTid_SVC_L1_NOLOSS)355 TEST_P (EncodeDecodeTestAPI, GetOptionTid_SVC_L1_NOLOSS) {
356 SLTRMarkingFeedback m_LTR_Marking_Feedback;
357 SLTRRecoverRequest m_LTR_Recover_Request;
358 m_LTR_Recover_Request.uiIDRPicId = 0;
359 m_LTR_Recover_Request.iLayerId = 0;
360 m_LTR_Marking_Feedback.iLayerId = 0;
361 EncodeDecodeFileParamBase p = GetParam();
362 prepareParamDefault (2, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
363 param_.iTemporalLayerNum = (rand() % 4) + 1;
364 param_.iSpatialLayerNum = 2;
365 encoder_->Uninitialize();
366 int rv = encoder_->InitializeExt (¶m_);
367 ASSERT_TRUE (rv == cmResultSuccess);
368 m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
369
370 ASSERT_TRUE (InitialEncDec (p.width, p.height));
371 int32_t iTraceLevel = WELS_LOG_QUIET;
372 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
373 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
374 int32_t iSpsPpsIdAddition = 1;
375 encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
376 int32_t iIDRPeriod = 60;
377 encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
378 SLTRConfig sLtrConfigVal;
379 sLtrConfigVal.bEnableLongTermReference = 1;
380 sLtrConfigVal.iLTRRefNum = 1;
381 encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
382 int32_t iLtrPeriod = 2;
383 encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
384 int iIdx = 0;
385 while (iIdx <= p.numframes) {
386 EncodeOneFrame (1);
387 if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
388 ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
389 }
390 //decoding after each encoding frame
391 int len = 0;
392 encToDecData (info, len);
393 unsigned char* pData[3] = { NULL };
394 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
395 ExtractDidNal (&info, len, &m_SLostSim, 1);
396 rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
397 int iTid = -1;
398 decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
399 ASSERT_EQ (iTid, -1);
400 m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
401 LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
402 rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
403 decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
404 ASSERT_EQ (iTid, info.sLayerInfo[0].uiTemporalId);
405 LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
406 LTRMarkFeedback (decoder_, encoder_, &m_LTR_Marking_Feedback, rv);
407 iIdx++;
408 }
409 }
410
411
412
TEST_P(EncodeDecodeTestAPI,SetOption_Trace)413 TEST_P (EncodeDecodeTestAPI, SetOption_Trace) {
414 SLTRMarkingFeedback m_LTR_Marking_Feedback;
415 SLTRRecoverRequest m_LTR_Recover_Request;
416 m_LTR_Recover_Request.uiIDRPicId = 0;
417 m_LTR_Recover_Request.iLayerId = 0;
418 m_LTR_Marking_Feedback.iLayerId = 0;
419 EncodeDecodeFileParamBase p = GetParam();
420 prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
421 param_.iSpatialLayerNum = 1;
422
423 int rv = encoder_->InitializeExt (¶m_);
424 ASSERT_TRUE (rv == cmResultSuccess);
425 m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
426
427 ASSERT_TRUE (InitialEncDec (p.width, p.height));
428 int32_t iTraceLevel = WELS_LOG_QUIET;
429 pFunc = TestOutPutTrace;
430 pTraceInfo = &sTrace;
431 sTrace.iTarLevel = iTraceLevel;
432 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
433 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
434 encoder_->SetOption (ENCODER_OPTION_TRACE_CALLBACK, &pFunc);
435 encoder_->SetOption (ENCODER_OPTION_TRACE_CALLBACK_CONTEXT, &pTraceInfo);
436 decoder_->SetOption (DECODER_OPTION_TRACE_CALLBACK, &pFunc);
437 decoder_->SetOption (DECODER_OPTION_TRACE_CALLBACK_CONTEXT, &pTraceInfo);
438
439
440 int32_t iSpsPpsIdAddition = 1;
441 encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
442 int32_t iIDRPeriod = 60;
443 encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
444 SLTRConfig sLtrConfigVal;
445 sLtrConfigVal.bEnableLongTermReference = 1;
446 sLtrConfigVal.iLTRRefNum = 1;
447 encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
448 int32_t iLtrPeriod = 2;
449 encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
450 int iIdx = 0;
451 int iLossIdx = 0;
452 bool bVCLLoss = false;
453 while (iIdx <= p.numframes) {
454 iTraceLevel = rand() % 33;
455 sTrace.iTarLevel = iTraceLevel;
456 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
457 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
458 EncodeOneFrame (1);
459 if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
460 ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
461 }
462 //decoding after each encoding frame
463 int len = 0;
464 encToDecData (info, len);
465 unsigned char* pData[3] = { NULL };
466 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
467 ExtractDidNal (&info, len, &m_SLostSim, 0);
468 SimulateNALLoss (info.sLayerInfo[0].pBsBuf, len, &m_SLostSim, p.pLossSequence, p.bLostPara, iLossIdx, bVCLLoss);
469 rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
470 m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
471 LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
472 rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
473 LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
474 LTRMarkFeedback (decoder_, encoder_, &m_LTR_Marking_Feedback, rv);
475 iIdx++;
476 }
477 }
478
TEST_P(EncodeDecodeTestAPI,SetOption_Trace_NULL)479 TEST_P (EncodeDecodeTestAPI, SetOption_Trace_NULL) {
480 SLTRMarkingFeedback m_LTR_Marking_Feedback;
481 SLTRRecoverRequest m_LTR_Recover_Request;
482 m_LTR_Recover_Request.uiIDRPicId = 0;
483 m_LTR_Recover_Request.iLayerId = 0;
484 m_LTR_Marking_Feedback.iLayerId = 0;
485 EncodeDecodeFileParamBase p = GetParam();
486 prepareParamDefault (1, p.slicenum, p.width, p.height, p.frameRate, ¶m_);
487 param_.iSpatialLayerNum = 1;
488 int rv = encoder_->InitializeExt (¶m_);
489 ASSERT_TRUE (rv == cmResultSuccess);
490 m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
491
492 ASSERT_TRUE (InitialEncDec (p.width, p.height));
493
494 int32_t iTraceLevel = WELS_LOG_QUIET;
495 pFunc = NULL;
496 pTraceInfo = NULL;
497 encoder_->SetOption (ENCODER_OPTION_TRACE_CALLBACK, &pFunc);
498 encoder_->SetOption (ENCODER_OPTION_TRACE_CALLBACK_CONTEXT, &pTraceInfo);
499 decoder_->SetOption (DECODER_OPTION_TRACE_CALLBACK, &pFunc);
500 decoder_->SetOption (DECODER_OPTION_TRACE_CALLBACK_CONTEXT, &pTraceInfo);
501 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
502 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
503
504 int32_t iSpsPpsIdAddition = 1;
505 encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
506 int32_t iIDRPeriod = 60;
507 encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
508 SLTRConfig sLtrConfigVal;
509 sLtrConfigVal.bEnableLongTermReference = 1;
510 sLtrConfigVal.iLTRRefNum = 1;
511 encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
512 int32_t iLtrPeriod = 2;
513 encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
514 int iIdx = 0;
515 int iLossIdx = 0;
516 bool bVCLLoss = false;
517 while (iIdx <= p.numframes) {
518 iTraceLevel = rand() % 33;
519 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
520 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
521 EncodeOneFrame (1);
522 if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
523 ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
524 }
525 //decoding after each encoding frame
526 int len = 0;
527 encToDecData (info, len);
528 unsigned char* pData[3] = { NULL };
529 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
530 ExtractDidNal (&info, len, &m_SLostSim, 0);
531 SimulateNALLoss (info.sLayerInfo[0].pBsBuf, len, &m_SLostSim, p.pLossSequence, p.bLostPara, iLossIdx, bVCLLoss);
532 rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
533 m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
534 LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
535 rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
536 LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
537 LTRMarkFeedback (decoder_, encoder_, &m_LTR_Marking_Feedback, rv);
538 iIdx++;
539 }
540 }
541
542
543
544
545 class DecodeCrashTestAPI : public ::testing::TestWithParam<EncodeDecodeFileParamBase>, public EncodeDecodeTestBase {
546 public:
SetUp()547 void SetUp() {
548 EncodeDecodeTestBase::SetUp();
549 ucBuf_ = NULL;
550 ucBuf_ = new unsigned char [1000000];
551 ASSERT_TRUE (ucBuf_ != NULL);
552 }
553
TearDown()554 void TearDown() {
555 EncodeDecodeTestBase::TearDown();
556 if (NULL != ucBuf_) {
557 delete[] ucBuf_;
558 ucBuf_ = NULL;
559 }
560 ASSERT_TRUE (ucBuf_ == NULL);
561 }
562
prepareParam(int iLayerNum,int iSliceNum,int width,int height,float framerate,SEncParamExt * pParam)563 void prepareParam (int iLayerNum, int iSliceNum, int width, int height, float framerate, SEncParamExt* pParam) {
564 memset (pParam, 0, sizeof (SEncParamExt));
565 EncodeDecodeTestBase::prepareParam (iLayerNum, iSliceNum, width, height, framerate, pParam);
566 }
567
EncodeOneFrame()568 void EncodeOneFrame() {
569 int frameSize = EncPic.iPicWidth * EncPic.iPicHeight * 3 / 2;
570 memset (buf_.data(), iRandValue, (frameSize >> 2));
571 memset (buf_.data() + (frameSize >> 2), rand() % 256, (frameSize - (frameSize >> 2)));
572 int rv = encoder_->EncodeFrame (&EncPic, &info);
573 ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnknownReason);
574 }
575 protected:
576 unsigned char* ucBuf_;
577 };
578
579 struct EncodeDecodeParamBase {
580 int width;
581 int height;
582 float frameRate;
583 int iTarBitrate;
584 };
585
586 #define NUM_OF_POSSIBLE_RESOLUTION (9)
587 static const EncodeDecodeParamBase kParamArray[] = {
588 {160, 90, 6.0f, 250000},
589 {90, 160, 6.0f, 250000},
590 {320, 180, 12.0f, 500000},
591 {180, 320, 12.0f, 500000},
592 {480, 270, 12.0f, 600000},
593 {270, 480, 12.0f, 600000},
594 {640, 360, 24.0f, 800000},
595 {360, 640, 24.0f, 800000},
596 {1280, 720, 24.0f, 1000000},
597 };
598
599 //#define DEBUG_FILE_SAVE_CRA
TEST_F(DecodeCrashTestAPI,DecoderCrashTest)600 TEST_F (DecodeCrashTestAPI, DecoderCrashTest) {
601 uint32_t uiGet;
602 encoder_->Uninitialize();
603
604 //do tests until crash
605 unsigned int uiLoopRound = 0;
606 unsigned char* pucBuf = ucBuf_;
607 int iDecAuSize;
608 #ifdef DEBUG_FILE_SAVE_CRA
609 //open file to save tested BS
610 FILE* fDataFile = fopen ("test_crash.264", "wb");
611 FILE* fLenFile = fopen ("test_crash_len.log", "w");
612 int iFileSize = 0;
613 #endif
614
615 //set eCurStrategy for one test
616 EParameterSetStrategy eCurStrategy = CONSTANT_ID;
617 switch (rand() % 7) {
618 case 1:
619 eCurStrategy = INCREASING_ID;
620 break;
621 case 2:
622 eCurStrategy = SPS_LISTING;
623 break;
624 case 3:
625 eCurStrategy = SPS_LISTING_AND_PPS_INCREASING;
626 break;
627 case 6:
628 eCurStrategy = SPS_PPS_LISTING;
629 break;
630 default:
631 //using the initial value
632 break;
633 }
634
635 do {
636 int iTotalFrameNum = (rand() % 100) + 1;
637 int iSeed = rand() % NUM_OF_POSSIBLE_RESOLUTION;
638 EncodeDecodeParamBase p = kParamArray[iSeed];
639 #ifdef DEBUG_FILE_SAVE_CRA
640 printf ("using param set %d in loop %d\n", iSeed, uiLoopRound);
641 #endif
642 //Initialize Encoder
643 prepareParam (1, 1, p.width, p.height, p.frameRate, ¶m_);
644 param_.iRCMode = RC_TIMESTAMP_MODE;
645 param_.iTargetBitrate = p.iTarBitrate;
646 param_.uiIntraPeriod = 0;
647 param_.eSpsPpsIdStrategy = eCurStrategy;
648 param_.bEnableBackgroundDetection = true;
649 param_.bEnableSceneChangeDetect = (rand() % 3) ? true : false;
650 param_.bPrefixNalAddingCtrl = (rand() % 2) ? true : false;
651 param_.iEntropyCodingModeFlag = 0;
652 param_.bEnableFrameSkip = true;
653 param_.iMultipleThreadIdc = 0;
654 param_.sSpatialLayers[0].iSpatialBitrate = p.iTarBitrate;
655 param_.sSpatialLayers[0].iMaxSpatialBitrate = p.iTarBitrate << 1;
656 param_.sSpatialLayers[0].sSliceArgument.uiSliceMode = (rand() % 2) ? SM_SIZELIMITED_SLICE : SM_SINGLE_SLICE;
657 if (param_.sSpatialLayers[0].sSliceArgument.uiSliceMode == SM_SIZELIMITED_SLICE) {
658 param_.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = 1400;
659 param_.uiMaxNalSize = 1400;
660 } else {
661 param_.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = 0;
662 param_.uiMaxNalSize = 0;
663 }
664
665 int rv = encoder_->InitializeExt (¶m_);
666 ASSERT_TRUE (rv == cmResultSuccess);
667 decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
668 EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY); //default value should be ERROR_CON_SLICE_COPY
669 int32_t iTraceLevel = WELS_LOG_QUIET;
670 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
671 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
672
673 //Start for enc/dec
674 int iIdx = 0;
675 unsigned char* pData[3] = { NULL };
676
677 EncodeDecodeFileParamBase pInput; //to conform with old functions
678 pInput.width = p.width;
679 pInput.height = p.height;
680 pInput.frameRate = p.frameRate;
681 ASSERT_TRUE (prepareEncDecParam (pInput));
682 while (iIdx++ < iTotalFrameNum) { // loop in frame
683 EncodeOneFrame();
684 #ifdef DEBUG_FILE_SAVE_CRA
685 //reset file if file size large
686 if ((info.eFrameType == videoFrameTypeIDR) && (iFileSize >= (1 << 25))) {
687 fclose (fDataFile);
688 fDataFile = fopen ("test_crash.264", "wb");
689 iFileSize = 0;
690 decoder_->Uninitialize();
691
692 SDecodingParam decParam;
693 memset (&decParam, 0, sizeof (SDecodingParam));
694 decParam.uiTargetDqLayer = UCHAR_MAX;
695 decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
696 decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
697
698 rv = decoder_->Initialize (&decParam);
699 ASSERT_EQ (0, rv);
700 }
701 #endif
702 if (info.eFrameType == videoFrameTypeSkip)
703 continue;
704 //deal with packets
705 unsigned char* pBsBuf;
706 iDecAuSize = 0;
707 pucBuf = ucBuf_; //init buf start pos for decoder usage
708 for (int iLayerNum = 0; iLayerNum < info.iLayerNum; iLayerNum++) {
709 SLayerBSInfo* pLayerBsInfo = &info.sLayerInfo[iLayerNum];
710 pBsBuf = info.sLayerInfo[iLayerNum].pBsBuf;
711 int iTotalNalCnt = pLayerBsInfo->iNalCount;
712 for (int iNalCnt = 0; iNalCnt < iTotalNalCnt; iNalCnt++) { //loop in NAL
713 int iPacketSize = pLayerBsInfo->pNalLengthInByte[iNalCnt];
714 //packet loss
715 int iLossRateRange = (uiLoopRound % 100) + 1; //1-100
716 int iLossRate = (rand() % iLossRateRange);
717 bool bPacketLost = (rand() % 101) > (100 -
718 iLossRate); // [0, (100-iLossRate)] indicates NO LOSS, (100-iLossRate, 100] indicates LOSS
719 if (!bPacketLost) { //no loss
720 memcpy (pucBuf, pBsBuf, iPacketSize);
721 pucBuf += iPacketSize;
722 iDecAuSize += iPacketSize;
723 }
724 #ifdef DEBUG_FILE_SAVE_CRA
725 else {
726 printf ("lost packet size=%d at frame-type=%d at loss rate %d (%d)\n", iPacketSize, info.eFrameType, iLossRate,
727 iLossRateRange);
728 }
729 #endif
730 //update bs info
731 pBsBuf += iPacketSize;
732 } //nal
733 } //layer
734
735 #ifdef DEBUG_FILE_SAVE_CRA
736 //save to file
737 fwrite (ucBuf_, 1, iDecAuSize, fDataFile);
738 fflush (fDataFile);
739 iFileSize += iDecAuSize;
740
741 //save to len file
742 unsigned long ulTmp[4];
743 ulTmp[0] = ulTmp[1] = ulTmp[2] = iIdx;
744 ulTmp[3] = iDecAuSize;
745 fwrite (ulTmp, sizeof (unsigned long), 4, fLenFile); // index, timeStamp, data size
746 fflush (fLenFile);
747 #endif
748
749 //decode
750 pData[0] = pData[1] = pData[2] = 0;
751 memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
752
753 rv = decoder_->DecodeFrame2 (ucBuf_, iDecAuSize, pData, &dstBufInfo_);
754 rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
755 //guarantee decoder EC status
756 decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
757 EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY);
758 } //frame
759 uiLoopRound ++;
760 if (uiLoopRound >= (1 << 30))
761 uiLoopRound = 0;
762 #ifdef DEBUG_FILE_SAVE_CRA
763 if (uiLoopRound % 100 == 0)
764 printf ("run %d times.\n", uiLoopRound);
765 } while (1); //while (iLoopRound<100);
766 fclose (fDataFile);
767 fclose (fLenFile);
768 #else
769 }
770 while (uiLoopRound < 10);
771 #endif
772
773 }
774
775 const uint32_t kiTotalLayer = 3; //DO NOT CHANGE!
776 const uint32_t kiSliceNum = 2; //DO NOT CHANGE!
777 const uint32_t kiWidth = 160; //DO NOT CHANGE!
778 const uint32_t kiHeight = 96; //DO NOT CHANGE!
779 const uint32_t kiFrameRate = 12; //DO NOT CHANGE!
780 const uint32_t kiFrameNum = 100; //DO NOT CHANGE!
781 const char* const pHashStr[][2] = { //DO NOT CHANGE!
782 // Allow for different output depending on whether averaging is done
783 // vertically or horizontally first when downsampling.
784 { "d5fb6d72f8cc0ea4b037e883598c162fd32b475d", "0fc7e06d0d766ac911730da2aa9e953bc858a161" },
785 { "17203f07486e895aef7c1bf94133fd731caba572", "1d47de674c9c44d8292ee00fa053a42bb9383614" },
786 { "86bf890aef2abe24abe40ebe3d9ec76a25ddebe7", "43eaac708413c109ca120c5d570176f1c9b4036c" }
787 };
788
789 class DecodeParseAPI : public ::testing::TestWithParam<EncodeDecodeFileParamBase>, public EncodeDecodeTestBase {
790 public:
DecodeParseAPI()791 DecodeParseAPI() {
792 memset (&BsInfo_, 0, sizeof (SParserBsInfo));
793 fYuv_ = NULL;
794 iWidth_ = 0;
795 iHeight_ = 0;
796 memset (&ctx_, 0, sizeof (SHA1Context));
797 }
SetUp()798 void SetUp() {
799 SHA1Reset (&ctx_);
800 EncodeDecodeTestBase::SetUp();
801
802 if (decoder_)
803 decoder_->Uninitialize();
804 SDecodingParam decParam;
805 memset (&decParam, 0, sizeof (SDecodingParam));
806 decParam.uiTargetDqLayer = UCHAR_MAX;
807 decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
808 decParam.bParseOnly = true;
809 decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
810
811 int rv = decoder_->Initialize (&decParam);
812 ASSERT_EQ (0, rv);
813 memset (&BsInfo_, 0, sizeof (SParserBsInfo));
814 const char* sFileName = "res/CiscoVT2people_160x96_6fps.yuv";
815 #if defined(ANDROID_NDK)
816 std::string filename = std::string ("/sdcard/") + sFileName;
817 ASSERT_TRUE ((fYuv_ = fopen (filename.c_str(), "rb")) != NULL);
818 #else
819 ASSERT_TRUE ((fYuv_ = fopen (sFileName, "rb")) != NULL);
820 #endif
821 iWidth_ = kiWidth;
822 iHeight_ = kiHeight;
823 }
TearDown()824 void TearDown() {
825 EncodeDecodeTestBase::TearDown();
826 if (fYuv_ != NULL) {
827 fclose (fYuv_);
828 fYuv_ = NULL;
829 }
830 }
831
prepareEncDecParam(const EncodeDecodeFileParamBase p)832 bool prepareEncDecParam (const EncodeDecodeFileParamBase p) {
833 if (!EncodeDecodeTestBase::prepareEncDecParam (p))
834 return false;
835 unsigned char* pTmpPtr = BsInfo_.pDstBuff; //store for restore
836 memset (&BsInfo_, 0, sizeof (SParserBsInfo));
837 BsInfo_.pDstBuff = pTmpPtr;
838 return true;
839 }
840
MockInputData(uint8_t * pData,int32_t iSize)841 void MockInputData (uint8_t* pData, int32_t iSize) {
842 int32_t iCurr = 0;
843 while (iCurr < iSize) {
844 * (pData + iCurr) = (* (pData + iCurr) + (rand() % 20) + 256) & 0x00ff;
845 iCurr++;
846 }
847 }
848
EncodeOneFrame(bool bMock)849 void EncodeOneFrame (bool bMock) {
850 int iFrameSize = iWidth_ * iHeight_ * 3 / 2;
851 int iSize = (int) fread (buf_.data(), sizeof (char), iFrameSize, fYuv_);
852 if (feof (fYuv_) || iSize != iFrameSize) {
853 rewind (fYuv_);
854 iSize = (int) fread (buf_.data(), sizeof (char), iFrameSize, fYuv_);
855 ASSERT_TRUE (iSize == iFrameSize);
856 }
857 if (bMock) {
858 MockInputData (buf_.data(), iWidth_ * iHeight_);
859 }
860 int rv = encoder_->EncodeFrame (&EncPic, &info);
861 ASSERT_TRUE (rv == cmResultSuccess || rv == cmUnknownReason);
862 }
863
prepareParam(int iLayerNum,int iSliceNum,int width,int height,float framerate,SEncParamExt * pParam)864 void prepareParam (int iLayerNum, int iSliceNum, int width, int height, float framerate, SEncParamExt* pParam) {
865 memset (pParam, 0, sizeof (SEncParamExt));
866 EncodeDecodeTestBase::prepareParam (iLayerNum, iSliceNum, width, height, framerate, pParam);
867 }
868
869 protected:
870 SParserBsInfo BsInfo_;
871 FILE* fYuv_;
872 int iWidth_;
873 int iHeight_;
874 SHA1Context ctx_;
875 };
876
877 //#define DEBUG_FILE_SAVE_PARSEONLY_GENERAL
TEST_F(DecodeParseAPI,ParseOnly_General)878 TEST_F (DecodeParseAPI, ParseOnly_General) {
879 EncodeDecodeFileParamBase p;
880 p.width = iWidth_;
881 p.height = iHeight_;
882 p.frameRate = kiFrameRate;
883 p.numframes = kiFrameNum;
884 prepareParam (kiTotalLayer, kiSliceNum, p.width, p.height, p.frameRate, ¶m_);
885 param_.iSpatialLayerNum = kiTotalLayer;
886 encoder_->Uninitialize();
887 int rv = encoder_->InitializeExt (¶m_);
888 ASSERT_TRUE (rv == 0);
889 int32_t iTraceLevel = WELS_LOG_QUIET;
890 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
891 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
892 uint32_t uiTargetLayerId = rand() % kiTotalLayer; //run only once
893 #ifdef DEBUG_FILE_SAVE_PARSEONLY_GENERAL
894 FILE* fDec = fopen ("output.264", "wb");
895 FILE* fEnc = fopen ("enc.264", "wb");
896 FILE* fExtract = fopen ("extract.264", "wb");
897 #endif
898 if (uiTargetLayerId < kiTotalLayer) { //should always be true
899 //Start for enc
900 int iLen = 0;
901 ASSERT_TRUE (prepareEncDecParam (p));
902 int iFrame = 0;
903
904 while (iFrame < p.numframes) {
905 //encode
906 EncodeOneFrame (0);
907 //extract target layer data
908 encToDecData (info, iLen);
909 #ifdef DEBUG_FILE_SAVE_PARSEONLY_GENERAL
910 fwrite (info.sLayerInfo[0].pBsBuf, iLen, 1, fEnc);
911 #endif
912 ExtractDidNal (&info, iLen, &m_SLostSim, uiTargetLayerId);
913 #ifdef DEBUG_FILE_SAVE_PARSEONLY_GENERAL
914 fwrite (info.sLayerInfo[0].pBsBuf, iLen, 1, fExtract);
915 #endif
916 //parseonly
917 //BsInfo_.pDstBuff = new unsigned char [1000000];
918 rv = decoder_->DecodeParser (info.sLayerInfo[0].pBsBuf, iLen, &BsInfo_);
919 EXPECT_TRUE (rv == 0);
920 EXPECT_TRUE (BsInfo_.iNalNum == 0);
921 rv = decoder_->DecodeParser (NULL, 0, &BsInfo_);
922 EXPECT_TRUE (rv == 0);
923 EXPECT_TRUE (BsInfo_.iNalNum != 0);
924 //get final output bs
925 iLen = 0;
926 int i = 0;
927 while (i < BsInfo_.iNalNum) {
928 iLen += BsInfo_.pNalLenInByte[i];
929 i++;
930 }
931 #ifdef DEBUG_FILE_SAVE_PARSEONLY_GENERAL
932 fwrite (BsInfo_.pDstBuff, iLen, 1, fDec);
933 #endif
934 SHA1Input (&ctx_, BsInfo_.pDstBuff, iLen);
935 iFrame++;
936 }
937 //calculate final SHA1 value
938 unsigned char digest[SHA_DIGEST_LENGTH];
939 SHA1Result (&ctx_, digest);
940 if (!HasFatalFailure()) {
941 CompareHashAnyOf (digest, pHashStr[uiTargetLayerId], sizeof * pHashStr / sizeof** pHashStr);
942 }
943 } //while
944 #ifdef DEBUG_FILE_SAVE_PARSEONLY_GENERAL
945 fclose (fEnc);
946 fclose (fExtract);
947 fclose (fDec);
948 #endif
949 }
950
951 //This case is for one layer only, for incomplete frame input
952 //First slice is loss for random one picture with 2 slices per pic
TEST_F(DecodeParseAPI,ParseOnly_SpecSliceLoss)953 TEST_F (DecodeParseAPI, ParseOnly_SpecSliceLoss) {
954 int32_t iLayerNum = 1;
955 int32_t iSliceNum = 2;
956 EncodeDecodeFileParamBase p;
957 p.width = iWidth_;
958 p.height = iHeight_;
959 p.frameRate = kiFrameRate;
960 p.numframes = 5;
961 prepareParam (iLayerNum, iSliceNum, p.width, p.height, p.frameRate, ¶m_);
962 param_.iSpatialLayerNum = iLayerNum;
963 encoder_->Uninitialize();
964 int rv = encoder_->InitializeExt (¶m_);
965 ASSERT_TRUE (rv == 0);
966 int32_t iTraceLevel = WELS_LOG_QUIET;
967 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
968 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
969
970 int32_t iMissedPicNum = rand() % (p.numframes - 1) + 1; //IDR no loss
971 //Start for enc
972 int iLen = 0;
973 uint32_t uiGet;
974 ASSERT_TRUE (prepareEncDecParam (p));
975 int iFrame = 0;
976
977 while (iFrame < p.numframes) {
978 //encode
979 EncodeOneFrame (0);
980 //parseonly
981 if (iFrame == iMissedPicNum) { //make current frame partly missing
982 //Frame: P, first slice loss
983 int32_t iTotalSliceSize = 0;
984 encToDecSliceData (0, 0, info, iTotalSliceSize); //slice 1 lost
985 encToDecSliceData (0, 1, info, iLen); //slice 2
986 decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
987 EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
988 rv = decoder_->DecodeParser (info.sLayerInfo[0].pBsBuf + iTotalSliceSize, iLen, &BsInfo_);
989 EXPECT_TRUE (rv == 0);
990 EXPECT_TRUE (BsInfo_.iNalNum == 0);
991 rv = decoder_->DecodeParser (NULL, 0, &BsInfo_);
992 EXPECT_TRUE (rv != 0);
993 } else { //normal frame, complete
994 encToDecData (info, iLen);
995 rv = decoder_->DecodeParser (info.sLayerInfo[0].pBsBuf, iLen, &BsInfo_);
996 EXPECT_TRUE (rv == 0); //parse correct
997 EXPECT_TRUE (BsInfo_.iNalNum == 0);
998 rv = decoder_->DecodeParser (NULL, 0, &BsInfo_);
999 if (iFrame < iMissedPicNum) { //correct frames, all OK with output
1000 EXPECT_TRUE (rv == 0);
1001 EXPECT_TRUE (BsInfo_.iNalNum != 0);
1002 } else { //(iFrame > iMissedPicNum), should output nothing as error
1003 EXPECT_TRUE (rv != 0);
1004 EXPECT_TRUE (BsInfo_.iNalNum == 0);
1005 }
1006 }
1007 iFrame++;
1008 } //while
1009 }
1010
TEST_F(DecodeParseAPI,ParseOnly_SpecStatistics)1011 TEST_F (DecodeParseAPI, ParseOnly_SpecStatistics) {
1012 //set params
1013 int32_t iLayerNum = 1;
1014 int32_t iSliceNum = 1;
1015 EncodeDecodeFileParamBase p;
1016 const int iLoopNum = 10;
1017 p.frameRate = kiFrameRate;
1018 p.numframes = 2; //encode 2 frames in each test
1019 p.width = iWidth_ = 16;
1020 p.height = iHeight_ = 16; //default start width/height = 16, will be modified each time
1021 int iTotalFrmCnt = 0;
1022 for (int i = 0; i < iLoopNum; ++i) {
1023 prepareParam (iLayerNum, iSliceNum, p.width, p.height, p.frameRate, ¶m_);
1024 param_.iSpatialLayerNum = iLayerNum;
1025 param_.sSpatialLayers[0].iDLayerQp = 40; //to revent size too limited to encoding fail
1026 encoder_->Uninitialize();
1027 int rv = encoder_->InitializeExt (¶m_);
1028 ASSERT_TRUE (rv == 0);
1029 int32_t iTraceLevel = WELS_LOG_QUIET;
1030 rv = encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1031 ASSERT_TRUE (rv == 0);
1032 rv = decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1033 ASSERT_TRUE (rv == 0);
1034 //Start for enc
1035 int iLen = 0;
1036 ASSERT_TRUE (prepareEncDecParam (p));
1037 int iFrame = 0;
1038 while (iFrame < p.numframes) {
1039 EncodeOneFrame (0);
1040 encToDecData (info, iLen);
1041 iFrame++;
1042 iTotalFrmCnt++;
1043 rv = decoder_->DecodeParser (info.sLayerInfo[0].pBsBuf, iLen, &BsInfo_);
1044 ASSERT_TRUE (rv == 0);
1045 ASSERT_TRUE (BsInfo_.iNalNum == 0);
1046 rv = decoder_->DecodeParser (NULL, 0, &BsInfo_);
1047 ASSERT_TRUE (rv == 0);
1048 ASSERT_TRUE (BsInfo_.iNalNum != 0);
1049 SDecoderStatistics sDecStat;
1050 rv = decoder_->GetOption (DECODER_OPTION_GET_STATISTICS, &sDecStat);
1051 ASSERT_TRUE (rv == 0);
1052 uint32_t uiProfile, uiLevel;
1053 rv = decoder_->GetOption (DECODER_OPTION_PROFILE, &uiProfile);
1054 ASSERT_TRUE (rv == 0);
1055 rv = decoder_->GetOption (DECODER_OPTION_LEVEL, &uiLevel);
1056 ASSERT_TRUE (rv == 0);
1057
1058 ASSERT_EQ (sDecStat.uiWidth, (unsigned int) p.width);
1059 ASSERT_EQ (sDecStat.uiHeight, (unsigned int) p.height);
1060 ASSERT_EQ (sDecStat.uiResolutionChangeTimes, (unsigned int) (i + 1));
1061 EXPECT_EQ (sDecStat.iCurrentActiveSpsId, 0);
1062 EXPECT_EQ (sDecStat.iCurrentActivePpsId, 0);
1063 ASSERT_EQ (sDecStat.uiDecodedFrameCount, (unsigned int) iTotalFrmCnt);
1064 ASSERT_EQ (sDecStat.uiProfile, uiProfile);
1065 ASSERT_EQ (sDecStat.uiLevel, uiLevel);
1066 EXPECT_TRUE (sDecStat.fActualAverageFrameSpeedInMs != 0.);
1067 EXPECT_TRUE (sDecStat.fAverageFrameSpeedInMs != 0.);
1068 EXPECT_TRUE (sDecStat.iAvgLumaQp != 0);
1069 EXPECT_EQ (sDecStat.uiIDRCorrectNum, (unsigned int) (i + 1));
1070 }
1071 //set next width & height
1072 p.width += 16;
1073 p.height += 16;
1074 if ((unsigned int) p.width > kiWidth) //exceeds max frame size
1075 p.width = 16;
1076 if ((unsigned int) p.height > kiHeight)
1077 p.height = 16;
1078 iWidth_ = p.width;
1079 iHeight_ = p.height;
1080 }
1081 }
1082
1083
1084 //Test parseonly crash cases
1085 class DecodeParseCrashAPI : public DecodeParseAPI {
1086 public:
DecodeParseCrashAPI()1087 DecodeParseCrashAPI() {
1088 }
SetUp()1089 void SetUp() {
1090 DecodeParseAPI::SetUp();
1091 iWidth_ = 1280;
1092 iHeight_ = 720;
1093
1094 ucBuf_ = NULL;
1095 ucBuf_ = new unsigned char[1000000];
1096 ASSERT_TRUE (ucBuf_ != NULL);
1097
1098 }
TearDown()1099 void TearDown() {
1100 DecodeParseAPI::TearDown();
1101 if (NULL != ucBuf_) {
1102 delete[] ucBuf_;
1103 ucBuf_ = NULL;
1104 }
1105 ASSERT_TRUE (ucBuf_ == NULL);
1106 }
1107
1108 protected:
1109 unsigned char* ucBuf_;
1110 };
1111
1112 //#define DEBUG_FILE_SAVE_PARSE_CRA1
TEST_F(DecodeParseCrashAPI,ParseOnlyCrash_General)1113 TEST_F (DecodeParseCrashAPI, ParseOnlyCrash_General) {
1114 if (fYuv_)
1115 fclose (fYuv_);
1116 const char* sFileName = "res/Cisco_Absolute_Power_1280x720_30fps.yuv";
1117 #if defined(ANDROID_NDK)
1118 std::string filename = std::string ("/sdcard/") + sFileName;
1119 ASSERT_TRUE ((fYuv_ = fopen (filename.c_str(), "rb")) != NULL);
1120 #else
1121 ASSERT_TRUE ((fYuv_ = fopen (sFileName, "rb")) != NULL);
1122 #endif
1123 uint32_t uiGet;
1124 encoder_->Uninitialize();
1125 //do tests until crash
1126 unsigned int uiLoopRound = 0;
1127 unsigned char* pucBuf = ucBuf_;
1128 int iDecAuSize;
1129 #ifdef DEBUG_FILE_SAVE_PARSE_CRA1
1130 //open file to save tested BS
1131 FILE* fDataFile = fopen ("test_parseonly_crash.264", "wb");
1132 FILE* fLenFile = fopen ("test_parseonly_crash_len.log", "w");
1133 int iFileSize = 0;
1134 #endif
1135
1136 do {
1137 #ifdef DEBUG_FILE_SAVE_PARSE_CRA1
1138 int iTotalFrameNum = (rand() % 1200) + 1;
1139 #else
1140 int iTotalFrameNum = (rand() % 100) + 1;
1141 #endif
1142 EncodeDecodeParamBase p = kParamArray[8]; //720p by default
1143
1144 //Initialize Encoder
1145 prepareParam (1, 4, p.width, p.height, p.frameRate, ¶m_);
1146 param_.iRCMode = RC_TIMESTAMP_MODE;
1147 param_.iTargetBitrate = p.iTarBitrate;
1148 param_.uiIntraPeriod = 0;
1149 param_.eSpsPpsIdStrategy = CONSTANT_ID;
1150 param_.bEnableBackgroundDetection = true;
1151 param_.bEnableSceneChangeDetect = (rand() % 3) ? true : false;
1152 param_.bPrefixNalAddingCtrl = 0;// (rand() % 2) ? true : false;
1153 param_.iEntropyCodingModeFlag = 0;
1154 param_.bEnableFrameSkip = true;
1155 param_.iMultipleThreadIdc = 0;
1156 param_.sSpatialLayers[0].iSpatialBitrate = p.iTarBitrate;
1157 param_.sSpatialLayers[0].iMaxSpatialBitrate = p.iTarBitrate << 1;
1158 param_.sSpatialLayers[0].sSliceArgument.uiSliceMode =
1159 SM_FIXEDSLCNUM_SLICE; // (rand() % 2) ? SM_SIZELIMITED_SLICE : SM_SINGLE_SLICE;
1160 if (param_.sSpatialLayers[0].sSliceArgument.uiSliceMode == SM_SIZELIMITED_SLICE) {
1161 param_.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = 1400;
1162 param_.uiMaxNalSize = 1400;
1163 } else {
1164 param_.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint = 0;
1165 param_.uiMaxNalSize = 0;
1166 }
1167
1168 int rv = encoder_->InitializeExt (¶m_);
1169 ASSERT_TRUE (rv == cmResultSuccess);
1170 decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
1171 EXPECT_EQ (uiGet, (uint32_t)ERROR_CON_DISABLE); //default value should be ERROR_CON_SLICE_COPY
1172 int32_t iTraceLevel = WELS_LOG_QUIET;
1173 encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1174 decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
1175
1176 //Start for enc/dec
1177 int iIdx = 0;
1178 unsigned char* pData[3] = { NULL };
1179
1180 EncodeDecodeFileParamBase pInput; //to conform with old functions
1181 pInput.width = p.width;
1182 pInput.height = p.height;
1183 pInput.frameRate = p.frameRate;
1184 prepareEncDecParam (pInput);
1185 while (iIdx++ < iTotalFrameNum) { // loop in frame
1186 EncodeOneFrame (1);
1187 #ifdef DEBUG_FILE_SAVE_PARSE_CRA1
1188 //reset file if file size large
1189 if ((info.eFrameType == videoFrameTypeIDR) && (iFileSize >= (1 << 25))) {
1190 fclose (fDataFile);
1191 fclose (fLenFile);
1192 fDataFile = fopen ("test_parseonly_crash.264", "wb");
1193 fLenFile = fopen ("test_parseonly_crash_len.log", "w");
1194 iFileSize = 0;
1195 decoder_->Uninitialize();
1196
1197 SDecodingParam decParam;
1198 memset (&decParam, 0, sizeof (SDecodingParam));
1199 decParam.uiTargetDqLayer = UCHAR_MAX;
1200 decParam.eEcActiveIdc = ERROR_CON_DISABLE;
1201 decParam.bParseOnly = true;
1202 decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
1203
1204 rv = decoder_->Initialize (&decParam);
1205 ASSERT_EQ (0, rv);
1206 }
1207 #endif
1208 if (info.eFrameType == videoFrameTypeSkip)
1209 continue;
1210 //deal with packets
1211 unsigned char* pBsBuf;
1212 iDecAuSize = 0;
1213 pucBuf = ucBuf_; //init buf start pos for decoder usage
1214 for (int iLayerNum = 0; iLayerNum < info.iLayerNum; iLayerNum++) {
1215 SLayerBSInfo* pLayerBsInfo = &info.sLayerInfo[iLayerNum];
1216 pBsBuf = info.sLayerInfo[iLayerNum].pBsBuf;
1217 int iTotalNalCnt = pLayerBsInfo->iNalCount;
1218 for (int iNalCnt = 0; iNalCnt < iTotalNalCnt; iNalCnt++) { //loop in NAL
1219 int iPacketSize = pLayerBsInfo->pNalLengthInByte[iNalCnt];
1220 //packet loss
1221 int iLossRateRange = (uiLoopRound % 20) + 1; //1-100
1222 int iLossRate = (rand() % iLossRateRange);
1223 bool bPacketLost = (rand() % 101) > (100 -
1224 iLossRate); // [0, (100-iLossRate)] indicates NO LOSS, (100-iLossRate, 100] indicates LOSS
1225 if (!bPacketLost) { //no loss
1226 memcpy (pucBuf, pBsBuf, iPacketSize);
1227 pucBuf += iPacketSize;
1228 iDecAuSize += iPacketSize;
1229 }
1230 //update bs info
1231 pBsBuf += iPacketSize;
1232 } //nal
1233 } //layer
1234
1235 #ifdef DEBUG_FILE_SAVE_PARSE_CRA1
1236 //save to file
1237 if (iDecAuSize != 0) {
1238 fwrite (ucBuf_, 1, iDecAuSize, fDataFile);
1239 fflush (fDataFile);
1240 iFileSize += iDecAuSize;
1241 }
1242
1243 //save to len file
1244 unsigned long ulTmp[4];
1245 ulTmp[0] = ulTmp[1] = ulTmp[2] = iIdx;
1246 ulTmp[3] = iDecAuSize;
1247 fwrite (ulTmp, sizeof (unsigned long), 4, fLenFile); // index, timeStamp, data size
1248 fflush (fLenFile);
1249 #endif
1250
1251 //decode
1252 pData[0] = pData[1] = pData[2] = 0;
1253 memset (&BsInfo_, 0, sizeof (SParserBsInfo));
1254
1255 rv = decoder_->DecodeParser (ucBuf_, iDecAuSize, &BsInfo_);
1256 rv = decoder_->DecodeParser (NULL, 0, &BsInfo_); //reconstruction
1257 //guarantee decoder EC status
1258 decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
1259 EXPECT_EQ (uiGet, (uint32_t)ERROR_CON_DISABLE);
1260 } //frame
1261 uiLoopRound++;
1262 if (uiLoopRound >= (1 << 30))
1263 uiLoopRound = 0;
1264 #ifdef DEBUG_FILE_SAVE_PARSE_CRA1
1265 if (uiLoopRound % 10 == 0)
1266 printf ("run %d times.\n", uiLoopRound);
1267 } while (1);
1268 fclose (fDataFile);
1269 fclose (fLenFile);
1270 #else
1271 }
1272 while (0);
1273 #endif
1274
1275 }
1276
1277