• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <gtest/gtest.h>
2 #include "codec_def.h"
3 #include "utils/BufferedData.h"
4 #include "utils/FileInputStream.h"
5 #include "BaseDecoderTest.h"
6 #include "BaseEncoderTest.h"
7 #include "wels_common_defs.h"
8 #include "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, &param_);
22   encoder_->Uninitialize();
23   int rv = encoder_->InitializeExt (&param_);
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, &param_);
58   encoder_->Uninitialize();
59   int rv = encoder_->InitializeExt (&param_);
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, &param_);
95   encoder_->Uninitialize();
96   int rv = encoder_->InitializeExt (&param_);
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, &param_);
145   encoder_->Uninitialize();
146   int rv = encoder_->InitializeExt (&param_);
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, &param_);
192   encoder_->Uninitialize();
193   int rv = encoder_->InitializeExt (&param_);
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, &param_);
235   param_.bPrefixNalAddingCtrl = false;
236   param_.iTemporalLayerNum = (rand() % 4) + 1;
237   encoder_->Uninitialize();
238   int rv = encoder_->InitializeExt (&param_);
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, &param_);
306   param_.bPrefixNalAddingCtrl = true;
307   param_.iTemporalLayerNum = (rand() % 4) + 1;
308   param_.iSpatialLayerNum = 1;
309   encoder_->Uninitialize();
310   int rv = encoder_->InitializeExt (&param_);
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, &param_);
363   param_.iTemporalLayerNum = (rand() % 4) + 1;
364   param_.iSpatialLayerNum = 2;
365   encoder_->Uninitialize();
366   int rv = encoder_->InitializeExt (&param_);
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, &param_);
421   param_.iSpatialLayerNum = 1;
422 
423   int rv = encoder_->InitializeExt (&param_);
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, &param_);
487   param_.iSpatialLayerNum = 1;
488   int rv = encoder_->InitializeExt (&param_);
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, &param_);
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 (&param_);
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, &param_);
885   param_.iSpatialLayerNum = kiTotalLayer;
886   encoder_->Uninitialize();
887   int rv = encoder_->InitializeExt (&param_);
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, &param_);
962   param_.iSpatialLayerNum = iLayerNum;
963   encoder_->Uninitialize();
964   int rv = encoder_->InitializeExt (&param_);
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, &param_);
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 (&param_);
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, &param_);
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 (&param_);
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