• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <gtest/gtest.h>
2 #include "codec_def.h"
3 #include "utils/BufferedData.h"
4 #include "utils/FileInputStream.h"
5 #include "BaseDecoderTest.h"
6 #include "BaseEncoderTest.h"
7 #include "wels_common_defs.h"
8 #include <string>
9 #include <vector>
10 #include "encode_decode_api_test.h"
11 using namespace WelsCommon;
12 
TEST_P(EncodeDecodeTestAPI,SetOptionECFlag_ERROR_CON_DISABLE)13 TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_DISABLE) {
14   SLTRMarkingFeedback m_LTR_Marking_Feedback;
15   SLTRRecoverRequest m_LTR_Recover_Request;
16   m_LTR_Recover_Request.uiIDRPicId = 0;
17   m_LTR_Recover_Request.iLayerId = 0;
18   m_LTR_Marking_Feedback.iLayerId = 0;
19   EncodeDecodeFileParamBase p = GetParam();
20   prepareParamDefault (1, p.slicenum,  p.width, p.height, p.frameRate, &param_);
21   param_.bEnableLongTermReference = true;
22   param_.iLTRRefNum = 1;
23   encoder_->Uninitialize();
24   int rv = encoder_->InitializeExt (&param_);
25   ASSERT_TRUE (rv == cmResultSuccess);
26   if (decoder_ != NULL) {
27     decoder_->Uninitialize();
28   }
29   SDecodingParam decParam;
30   memset (&decParam, 0, sizeof (SDecodingParam));
31   decParam.uiTargetDqLayer = UCHAR_MAX;
32   decParam.eEcActiveIdc = ERROR_CON_DISABLE;
33   decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
34   rv = decoder_->Initialize (&decParam);
35   ASSERT_EQ (0, rv);
36   m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
37 
38   ASSERT_TRUE (InitialEncDec (p.width, p.height));
39   int32_t iTraceLevel = WELS_LOG_QUIET;
40   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
41   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
42   int32_t iSpsPpsIdAddition = 1;
43   encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
44   int32_t iIDRPeriod = 60;
45   encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
46   SLTRConfig sLtrConfigVal;
47   sLtrConfigVal.bEnableLongTermReference = 1;
48   sLtrConfigVal.iLTRRefNum = 1;
49   encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
50   int32_t iLtrPeriod = 2;
51   encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
52   int iIdx = 0;
53   int iLossIdx = 0;
54   int iSkipedBytes;
55   bool bVCLLoss = false;
56   while (iIdx <= p.numframes) {
57     EncodeOneFrame (1);
58     if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
59       ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
60     }
61     //decoding after each encoding frame
62     int len = 0;
63     encToDecData (info, len);
64     unsigned char* pData[3] = { NULL };
65     memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
66     iSkipedBytes = SimulateNALLoss (info.sLayerInfo[0].pBsBuf, len, &m_SLostSim, p.pLossSequence, p.bLostPara, iLossIdx,
67                                     bVCLLoss);
68     rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
69     m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
70     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
71     rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
72     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
73     LTRMarkFeedback (decoder_, encoder_, &m_LTR_Marking_Feedback, rv);
74     if (iSkipedBytes && bVCLLoss) {
75       ASSERT_TRUE (dstBufInfo_.iBufferStatus == 0);
76     }
77     iIdx++;
78   }
79 }
80 
TEST_P(EncodeDecodeTestAPI,SetOptionECFlag_ERROR_CON_SLICE_COPY)81 TEST_P (EncodeDecodeTestAPI, SetOptionECFlag_ERROR_CON_SLICE_COPY) {
82   SLTRMarkingFeedback m_LTR_Marking_Feedback;
83   SLTRRecoverRequest m_LTR_Recover_Request;
84   m_LTR_Recover_Request.uiIDRPicId = 0;
85   m_LTR_Recover_Request.iLayerId = 0;
86   m_LTR_Marking_Feedback.iLayerId = 0;
87   EncodeDecodeFileParamBase p = GetParam();
88   prepareParamDefault (1, p.slicenum,  p.width, p.height, p.frameRate, &param_);
89   encoder_->Uninitialize();
90   int rv = encoder_->InitializeExt (&param_);
91   ASSERT_TRUE (rv == cmResultSuccess);
92   m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
93 
94   ASSERT_TRUE (InitialEncDec (p.width, p.height));
95   int32_t iTraceLevel = WELS_LOG_QUIET;
96   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
97   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
98   int32_t iSpsPpsIdAddition = 1;
99   encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
100   int32_t iIDRPeriod = 60;
101   encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
102   SLTRConfig sLtrConfigVal;
103   sLtrConfigVal.bEnableLongTermReference = 1;
104   sLtrConfigVal.iLTRRefNum = 1;
105   encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
106   int32_t iLtrPeriod = 2;
107   encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
108   int iIdx = 0;
109   int iLossIdx = 0;
110   int iSkipedBytes;
111   bool bVCLLoss = false;
112   while (iIdx <= p.numframes) {
113     EncodeOneFrame (1);
114     if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
115       ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
116     }
117     //decoding after each encoding frame
118     int len = 0;
119     encToDecData (info, len);
120     unsigned char* pData[3] = { NULL };
121     memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
122     iSkipedBytes = SimulateNALLoss (info.sLayerInfo[0].pBsBuf, len, &m_SLostSim, p.pLossSequence, p.bLostPara, iLossIdx,
123                                     bVCLLoss);
124     uint32_t uiEcIdc = rand() % 2 == 1 ? ERROR_CON_DISABLE : ERROR_CON_SLICE_COPY;
125     decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
126     rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
127     m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
128     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
129     rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
130     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
131     LTRMarkFeedback (decoder_, encoder_, &m_LTR_Marking_Feedback, rv);
132     iIdx++;
133   }
134   (void) iSkipedBytes;
135 }
136 
137 static const EncodeDecodeFileParamBase kFileParamArray[] = {
138   {300, 160, 96, 6.0f, 2, 1, "000000000000001010101010101010101010101001101010100000010101000011"},
139   {300, 140, 96, 6.0f, 4, 1, "000000000000001010101010101010101010101001101010100000010101000011"},
140   {300, 140, 96, 6.0f, 4, 1, "000000000000001010111010101011101010101001101010100000010101110011010101"},
141 };
142 
143 INSTANTIATE_TEST_CASE_P (EncodeDecodeTestAPIBase, EncodeDecodeTestAPI,
144                          ::testing::ValuesIn (kFileParamArray));
145 
TEST_P(EncodeDecodeTestAPI,SetOptionECIDC_GeneralSliceChange)146 TEST_P (EncodeDecodeTestAPI, SetOptionECIDC_GeneralSliceChange) {
147   uint32_t uiEcIdc;
148   uint32_t uiGet;
149   EncodeDecodeFileParamBase p = GetParam();
150   prepareParamDefault (1, p.slicenum,  p.width, p.height, p.frameRate, &param_);
151   param_.iSpatialLayerNum = 1;
152   encoder_->Uninitialize();
153   int rv = encoder_->InitializeExt (&param_);
154   ASSERT_TRUE (rv == cmResultSuccess);
155   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
156   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY); //default value should be ERROR_CON_SLICE_COPY
157 
158   uiEcIdc = 0;
159   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
160   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
161   EXPECT_EQ (uiGet, uiEcIdc);
162 
163   //Start for enc/dec
164 
165   ASSERT_TRUE (InitialEncDec (p.width, p.height));
166   int32_t iTraceLevel = WELS_LOG_QUIET;
167   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
168   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
169   int iIdx = 0;
170   bool bVCLLoss = false;
171   int iPacketNum;
172   int len;
173   int iTotalSliceSize;
174 
175   //enc/dec pictures
176   while (iIdx <= p.numframes) {
177     EncodeOneFrame (1);
178     //decoding after each encoding frame
179     len = 0;
180     iPacketNum = 0;
181     iTotalSliceSize = 0;
182     unsigned char* pData[3] = { NULL };
183     memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
184     while (iPacketNum < info.sLayerInfo[0].iNalCount) {
185       encToDecSliceData (0, iPacketNum, info, len);
186       uiEcIdc = (ERROR_CON_IDC) (rand() % 2);
187       decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
188       decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
189       EXPECT_EQ (uiGet, uiEcIdc);
190 
191       bVCLLoss = rand() & 1; //loss or not
192       if (!bVCLLoss) { //not loss
193         rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf + iTotalSliceSize,
194                                      info.sLayerInfo[0].pNalLengthInByte[iPacketNum], pData, &dstBufInfo_);
195         if (uiEcIdc == ERROR_CON_DISABLE) {
196           EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
197         }
198       }
199       //EC_IDC should not change till now
200       decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
201       EXPECT_EQ (uiGet, uiEcIdc);
202       //Set again inside
203       uiEcIdc = (ERROR_CON_IDC) (rand() % 2);
204       decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
205       decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
206       EXPECT_EQ (uiGet, uiEcIdc);
207 
208       rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
209       //EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
210       if (uiEcIdc == ERROR_CON_DISABLE && rv != 0) {
211         EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
212       }
213 
214       //deal with next slice
215       iTotalSliceSize += len;
216       iPacketNum++;
217     } //while slice
218     iIdx++;
219   } //while frame
220 }
221 
222 //This case contain 1 slice per picture
223 //coding order:                 0   1   2   3   4   5   6   7
224 //frame type:                   IDR P   P   P   P   P   P   P
225 //EC_IDC:                       0   0   0   2   0   0   1   1
226 //loss:                         N   Y   N   N   N   Y   Y   N
227 
TEST_F(EncodeDecodeTestAPI,SetOptionECIDC_SpecificFrameChange)228 TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificFrameChange) {
229   uint32_t uiEcIdc;
230   uint32_t uiGet;
231   EncodeDecodeFileParamBase p = kFileParamArray[0];
232   prepareParamDefault (1, p.slicenum,  p.width, p.height, p.frameRate, &param_);
233 
234   param_.iSpatialLayerNum = 1;
235   encoder_->Uninitialize();
236   int rv = encoder_->InitializeExt (&param_);
237   ASSERT_TRUE (rv == cmResultSuccess);
238   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
239   EXPECT_EQ (uiGet, (ERROR_CON_IDC) ERROR_CON_SLICE_COPY); //default value should be ERROR_CON_SLICE_COPY
240   int32_t iTraceLevel = WELS_LOG_QUIET;
241   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
242   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
243 
244   //set EC=DISABLE
245   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
246   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
247   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
248   EXPECT_EQ (uiGet, uiEcIdc);
249 
250   //Start for enc/dec
251   int iIdx = 0;
252   int len = 0;
253   unsigned char* pData[3] = { NULL };
254   ASSERT_TRUE (InitialEncDec (p.width, p.height));
255   //Frame 0: IDR, EC_IDC=DISABLE, loss = 0
256   EncodeOneFrame (1);
257   encToDecData (info, len);
258   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
259   EXPECT_EQ (uiGet, (ERROR_CON_IDC) ERROR_CON_DISABLE);
260   pData[0] = pData[1] = pData[2] = 0;
261   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
262   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
263   EXPECT_EQ (rv, 0);
264   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
265   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
266   EXPECT_EQ (rv, 0);
267   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1);
268   iIdx++;
269 
270   //Frame 1: P, EC_IDC=DISABLE, loss = 1
271   EncodeOneFrame (1);
272   iIdx++;
273 
274   //Frame 2: P, EC_IDC=DISABLE, loss = 0
275   EncodeOneFrame (1);
276   encToDecData (info, len);
277   pData[0] = pData[1] = pData[2] = 0;
278   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
279   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
280   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
281   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
282   EXPECT_EQ (rv, 0); //parse correct
283   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output
284   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
285   EXPECT_TRUE (rv != 0); //construction error due to data loss
286   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output due to EC DISABLE
287   iIdx++;
288 
289   //set EC=SLICE_COPY
290   uiEcIdc = (uint32_t) (ERROR_CON_SLICE_COPY);
291   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
292   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
293   EXPECT_EQ (uiGet, uiEcIdc);
294   //Frame 3: P, EC_IDC=SLICE_COPY, loss = 0
295   EncodeOneFrame (1);
296   encToDecData (info, len);
297   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
298   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY);
299   pData[0] = pData[1] = pData[2] = 0;
300   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
301   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
302   EXPECT_EQ (rv, 0); //parse correct
303   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output
304   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
305   EXPECT_TRUE (rv != 0); //construction error due to data loss
306   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1);
307   iIdx++;
308 
309   //set EC=DISABLE
310   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
311   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
312   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
313   EXPECT_EQ (uiGet, uiEcIdc);
314   //Frame 4: P, EC_IDC=DISABLE, loss = 0
315   EncodeOneFrame (1);
316   encToDecData (info, len);
317   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
318   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
319   pData[0] = pData[1] = pData[2] = 0;
320   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
321   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
322   EXPECT_EQ (rv, 0); //parse correct
323   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output
324   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
325   //Ref picture is ECed, so current status is ECed, when EC disable, NO output
326   EXPECT_TRUE (rv != 0);
327   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
328   iIdx++;
329 
330   //Frame 5: P, EC_IDC=DISABLE, loss = 1
331   EncodeOneFrame (1);
332   iIdx++;
333 
334   //set EC=FRAME_COPY
335   uiEcIdc = (uint32_t) (ERROR_CON_FRAME_COPY);
336   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
337   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
338   EXPECT_EQ (uiGet, uiEcIdc);
339   //Frame 6: P, EC_IDC=FRAME_COPY, loss = 1
340   EncodeOneFrame (1);
341   EXPECT_EQ (uiGet, uiEcIdc);
342   iIdx++;
343 
344   //Frame 7: P, EC_IDC=FRAME_COPY, loss = 0
345   EncodeOneFrame (1);
346   encToDecData (info, len);
347   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
348   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_FRAME_COPY);
349   pData[0] = pData[1] = pData[2] = 0;
350   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
351   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
352   EXPECT_TRUE (rv == 0); // Now the parse process is Error_None, and the reconstruction will has error return
353   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output
354   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
355   EXPECT_TRUE (rv != 0); //not sure if previous data drop would be detected in construction
356   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1);
357   iIdx++;
358 }
359 
360 //This case contain 2 slices per picture for IDR loss
361 //coding order:                 0   1   2   3   4
362 //frame type                    IDR P   P   P   P
363 //EC_IDC                        2   2   0   1   0
364 //loss (2 slice: 1,2):          2   0   0   1   0
365 
TEST_F(EncodeDecodeTestAPI,SetOptionECIDC_SpecificSliceChange_IDRLoss)366 TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRLoss) {
367   uint32_t uiEcIdc = 2; //default set as SLICE_COPY
368   uint32_t uiGet;
369   EncodeDecodeFileParamBase p = kFileParamArray[0];
370   prepareParamDefault (1, 2,  p.width, p.height, p.frameRate, &param_);
371   param_.iSpatialLayerNum = 1;
372   encoder_->Uninitialize();
373   int rv = encoder_->InitializeExt (&param_);
374   ASSERT_TRUE (rv == cmResultSuccess);
375   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
376   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
377   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY); //default value should be ERROR_CON_SLICE_COPY
378   int32_t iTraceLevel = WELS_LOG_QUIET;
379   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
380   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
381 
382   //Start for enc/dec
383   int iIdx = 0;
384   int len = 0;
385   unsigned char* pData[3] = { NULL };
386   int iTotalSliceSize = 0;
387 
388   ASSERT_TRUE (InitialEncDec (p.width, p.height));
389 
390   //Frame 0: IDR, EC_IDC=2, loss = 2
391   EncodeOneFrame (1);
392   iTotalSliceSize = 0;
393   encToDecSliceData (0, 0, info, len); //SPS
394   iTotalSliceSize = len;
395   encToDecSliceData (0, 1, info, len); //PPS
396   iTotalSliceSize += len;
397   encToDecSliceData (1, 0, info, len); //first slice
398   iTotalSliceSize += len;
399   //second slice loss
400   pData[0] = pData[1] = pData[2] = 0;
401   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
402   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
403   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY);
404   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, iTotalSliceSize, pData, &dstBufInfo_);
405   EXPECT_EQ (rv, 0); //parse correct
406   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
407   EXPECT_EQ (rv, 0); // Reconstruct first slice OK
408   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //slice incomplete, no output
409   iIdx++;
410 
411   //Frame 1: P, EC_IDC=2, loss = 0
412   //will clean SPS/PPS status
413   EncodeOneFrame (1);
414   encToDecData (info, len); //all slice together
415   pData[0] = pData[1] = pData[2] = 0;
416   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
417   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
418   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY);
419   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
420   EXPECT_TRUE ((rv & 32) != 0); //parse correct, but reconstruct ECed
421   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //ECed output for frame 0
422   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //ECed status, reconstruction current frame 1
423   EXPECT_TRUE ((rv & 32) != 0); //decoder ECed status
424   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //ECed output for frame 1
425   iIdx++;
426 
427   //set EC=DISABLE
428   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
429   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
430   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
431   EXPECT_EQ (uiGet, uiEcIdc);
432   //Frame 2: P, EC_IDC=0, loss = 0
433   /////will clean SPS/PPS status
434   EncodeOneFrame (1);
435   encToDecData (info, len); //all slice together
436   pData[0] = pData[1] = pData[2] = 0;
437   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
438   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
439   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
440   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
441   EXPECT_EQ (rv, 0); //parse correct
442   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
443   // Ref picture is ECed, so reconstructed picture is ECed
444   EXPECT_TRUE ((rv & 32) != 0);
445   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
446   iIdx++;
447 
448   //set EC=SLICE_COPY
449   uiEcIdc = (uint32_t) (ERROR_CON_FRAME_COPY);
450   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
451   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
452   EXPECT_EQ (uiGet, uiEcIdc);
453   //Frame 3: P, EC_IDC=2, loss = 1
454   EncodeOneFrame (1);
455   encToDecSliceData (0, 0, info, iTotalSliceSize); //slice 1 lost
456   encToDecSliceData (0, 1, info, len); //slice 2
457   pData[0] = pData[1] = pData[2] = 0;
458   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
459   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
460   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_FRAME_COPY);
461   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf + iTotalSliceSize, len, pData, &dstBufInfo_);
462   EXPECT_EQ (rv, 0); //parse correct
463   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
464   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
465   EXPECT_TRUE ((rv & 32) != 0);
466   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //slice loss
467   iIdx++;
468 
469   //set EC=DISABLE
470   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
471   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
472   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
473   EXPECT_EQ (uiGet, uiEcIdc);
474   //Frame 4: P, EC_IDC=0, loss = 0
475   EncodeOneFrame (1);
476   encToDecData (info, len); //all slice
477   pData[0] = pData[1] = pData[2] = 0;
478   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
479   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
480   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
481   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
482   EXPECT_TRUE (rv != 0);
483   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); // EC_IDC=0, previous picture slice lost, no output
484   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
485   EXPECT_TRUE (rv != 0);
486   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); // No ref picture, no output
487   iIdx++;
488 
489 }
490 
491 
492 
493 //This case contain 2 slices per picture for no IDR loss
494 //coding order:                 0   1   2   3   4   5
495 //frame type                    IDR P   P   P   P   IDR
496 //EC_IDC                        0   2   0   2   0   ^2^
497 //loss (2 slice: 1,2):          0   0   1   2   0   0
498 
TEST_F(EncodeDecodeTestAPI,SetOptionECIDC_SpecificSliceChange_IDRNoLoss)499 TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRNoLoss) {
500   uint32_t uiEcIdc;
501   uint32_t uiGet;
502   EncodeDecodeFileParamBase p = kFileParamArray[0];
503   prepareParamDefault (1, 2,  p.width, p.height, p.frameRate, &param_);
504   param_.iSpatialLayerNum = 1;
505   encoder_->Uninitialize();
506   int rv = encoder_->InitializeExt (&param_);
507   ASSERT_TRUE (rv == cmResultSuccess);
508   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
509   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY); //default value should be ERROR_CON_SLICE_COPY
510   int32_t iTraceLevel = WELS_LOG_QUIET;
511   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
512   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
513 
514   //Start for enc/dec
515   int iIdx = 0;
516   int len = 0;
517   unsigned char* pData[3] = { NULL };
518   int iTotalSliceSize = 0;
519 
520   ASSERT_TRUE (InitialEncDec (p.width, p.height));
521 
522   //set EC=DISABLE
523   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
524   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
525   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
526   EXPECT_EQ (uiGet, uiEcIdc);
527   //Frame 0: IDR, EC_IDC=0, loss = 0
528   //Expected result: all OK, 2nd Output
529   EncodeOneFrame (1);
530   encToDecData (info, len); //all slice
531   pData[0] = pData[1] = pData[2] = 0;
532   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
533   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
534   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
535   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
536   EXPECT_EQ (rv, 0); //parse correct
537   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
538   EXPECT_EQ (rv, 0); //parse correct
539   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //output frame 0
540   iIdx++;
541 
542   //Frame 1: P, EC_IDC=0, loss = 0
543   //Expected result: all OK, 2nd Output
544   EncodeOneFrame (1);
545   encToDecData (info, len); //all slice together
546   pData[0] = pData[1] = pData[2] = 0;
547   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
548   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
549   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
550   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
551   EXPECT_EQ (rv, 0); //parse correct
552   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //ECed output for frame 0
553   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction current frame 1
554   EXPECT_EQ (rv, 0); //parse correct
555   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //ECed output for frame 1
556   iIdx++;
557 
558   //Frame 2: P, EC_IDC=0, loss = 1
559   //Expected result: all OK, no Output
560   EncodeOneFrame (1);
561   encToDecSliceData (0, 0, info, iTotalSliceSize); // slice 1 lost
562   encToDecSliceData (0, 1, info, len); // slice 2 only
563   pData[0] = pData[1] = pData[2] = 0;
564   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
565   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
566   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
567   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf + iTotalSliceSize, len, pData, &dstBufInfo_);
568   EXPECT_EQ (rv, 0); //parse correct
569   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
570   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
571   EXPECT_EQ (rv, 0); //parse correct
572   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
573   iIdx++;
574 
575   //set EC=SLICE_COPY
576   uiEcIdc = (uint32_t) (ERROR_CON_SLICE_COPY);
577   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
578   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
579   EXPECT_EQ (uiGet, uiEcIdc);
580   //Frame 3: P, EC_IDC=2, loss = 2
581   //Expected result: neither OK, 1st Output
582   EncodeOneFrame (1);
583   encToDecSliceData (0, 0, info, len); //slice 1 only
584   pData[0] = pData[1] = pData[2] = 0;
585   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
586   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
587   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY);
588   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
589   EXPECT_TRUE ((rv & 32) != 0); //parse OK but frame 2 ECed
590   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //slice loss but ECed output Frame 2
591   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
592   EXPECT_TRUE ((rv & 32) != 0);
593   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //slice loss
594   iIdx++;
595 
596   //set EC=DISABLE
597   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
598   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
599   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
600   EXPECT_EQ (uiGet, uiEcIdc);
601   //Frame 4: P, EC_IDC=0, loss = 0
602   //Expected result: depends on DecodeFrame2 result. If OK, output; else ,no output
603   EncodeOneFrame (1);
604   encToDecData (info, len); //all slice
605   pData[0] = pData[1] = pData[2] = 0;
606   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
607   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
608   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
609   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
610   EXPECT_TRUE (rv != 0); //previous slice not outputted, will return error due to incomplete frame
611   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
612   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction,
613   // previous frame NOT output, no ref
614   EXPECT_TRUE (rv != 0);
615   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
616   iIdx++;
617 
618   //Frame 5: IDR, EC_IDC=2->0, loss = 0
619   //Expected result: depends on DecodeFrame2 result. If OK, output; else ,no output
620   int32_t iIDRPeriod = 1;
621   encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
622   EncodeOneFrame (1);
623   EXPECT_TRUE (info.eFrameType == videoFrameTypeIDR);
624   encToDecSliceData (0, 0, info, len); //SPS
625   iTotalSliceSize = len;
626   encToDecSliceData (0, 1, info, len); //PPS
627   iTotalSliceSize += len;
628   encToDecSliceData (1, 0, info, len); //slice 1
629   iTotalSliceSize += len;
630   //set EC=SLICE_COPY for slice 1
631   uiEcIdc = (uint32_t) (ERROR_CON_SLICE_COPY);
632   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
633   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
634   EXPECT_EQ (uiGet, uiEcIdc);
635   pData[0] = pData[1] = pData[2] = 0;
636   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
637   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, iTotalSliceSize, pData, &dstBufInfo_);
638   EXPECT_TRUE (rv == 0); // IDR status return error_free
639   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //frame incomplete
640   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction,
641   EXPECT_TRUE (rv == 0);
642   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
643   //set EC=DISABLE for slice 2
644   encToDecSliceData (1, 1, info, len); //slice 1
645   uiEcIdc = (int) (ERROR_CON_DISABLE);
646   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
647   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
648   EXPECT_EQ (uiGet, uiEcIdc);
649   pData[0] = pData[1] = pData[2] = 0;
650   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
651   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf + iTotalSliceSize, len, pData, &dstBufInfo_);
652   EXPECT_EQ (rv, 0); //Parse correct under no EC
653   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //frame incomplete
654   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction,
655   EXPECT_EQ (rv, 0);
656   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //output previous pic
657   iIdx++;
658 
659 }
660 
661 static const EncodeDecodeFileParamBase kSVCSwitch[] = {
662   {300, 160, 96, 6.0f, 2, 1, "120012130101012311201221323"},
663 };
664 
TEST_F(EncodeDecodeTestAPI,Engine_SVC_Switch_I)665 TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_I) {
666   SLTRMarkingFeedback m_LTR_Marking_Feedback;
667   SLTRRecoverRequest m_LTR_Recover_Request;
668   m_LTR_Recover_Request.uiIDRPicId = 0;
669   m_LTR_Recover_Request.iLayerId = 0;
670   m_LTR_Marking_Feedback.iLayerId = 0;
671   EncodeDecodeFileParamBase p = kSVCSwitch[0];
672   p.width = p.width << 2;
673   p.height = p.height << 2;
674   prepareParamDefault (4, p.slicenum, p.width, p.height, p.frameRate, &param_);
675   param_.iTemporalLayerNum = (rand() % 4) + 1;
676   param_.iSpatialLayerNum = 4;
677   encoder_->Uninitialize();
678   int rv = encoder_->InitializeExt (&param_);
679   ASSERT_TRUE (rv == cmResultSuccess);
680   m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
681 
682   ASSERT_TRUE (InitialEncDec (p.width, p.height));
683   int32_t iTraceLevel = WELS_LOG_QUIET;
684   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
685   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
686   int32_t iSpsPpsIdAddition = 1;
687   encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
688   int32_t iIDRPeriod = (int32_t) pow (2.0f, (param_.iTemporalLayerNum - 1)) * ((rand() % 5) + 1);
689   encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
690   SLTRConfig sLtrConfigVal;
691   sLtrConfigVal.bEnableLongTermReference = 1;
692   sLtrConfigVal.iLTRRefNum = 1;
693   encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
694   int32_t iLtrPeriod = 2;
695   encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
696   int iIdx = 0;
697   int iTarDid = 0;
698   while (iIdx <= p.numframes) {
699     EncodeOneFrame (1);
700     if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
701       ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
702     }
703     if (info.eFrameType == videoFrameTypeIDR) {
704       iTarDid = rand() % 4;
705     }
706     //decoding after each encoding frame
707     int len = 0;
708     encToDecData (info, len);
709     unsigned char* pData[3] = { NULL };
710     memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
711 
712     ExtractDidNal (&info, len, &m_SLostSim, iTarDid);
713     rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
714     ASSERT_EQ (rv, 0);
715     int iTid = -1;
716     decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
717     ASSERT_EQ (iTid, -1);
718     m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
719     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
720     rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
721     ASSERT_EQ (rv, 0);
722     decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
723     ASSERT_EQ (iTid, info.sLayerInfo[0].uiTemporalId);
724     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
725     LTRMarkFeedback (decoder_, encoder_, &m_LTR_Marking_Feedback, rv);
726     iIdx++;
727   }
728 }
729 
TEST_F(EncodeDecodeTestAPI,Engine_SVC_Switch_P)730 TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_P) {
731   SLTRMarkingFeedback m_LTR_Marking_Feedback;
732   SLTRRecoverRequest m_LTR_Recover_Request;
733   m_LTR_Recover_Request.uiIDRPicId = 0;
734   m_LTR_Recover_Request.iLayerId = 0;
735   m_LTR_Marking_Feedback.iLayerId = 0;
736   EncodeDecodeFileParamBase p = kSVCSwitch[0];
737   int iTarDid = 0;
738   int iLastDid = 0;
739   p.width = p.width << 2;
740   p.height = p.height << 2;
741   prepareParamDefault (4, p.slicenum, p.width, p.height, p.frameRate, &param_);
742   param_.iTemporalLayerNum = (rand() % 4) + 1;
743   param_.iSpatialLayerNum = 4;
744   encoder_->Uninitialize();
745   int rv = encoder_->InitializeExt (&param_);
746   ASSERT_TRUE (rv == cmResultSuccess);
747   m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
748 
749   ASSERT_TRUE (InitialEncDec (p.width, p.height));
750   int32_t iTraceLevel = WELS_LOG_QUIET;
751   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
752   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
753   int32_t iSpsPpsIdAddition = 1;
754   encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
755   int32_t iIDRPeriod = 60;
756   encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
757   SLTRConfig sLtrConfigVal;
758   sLtrConfigVal.bEnableLongTermReference = 1;
759   sLtrConfigVal.iLTRRefNum = 1;
760   encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
761   int32_t iLtrPeriod = 2;
762   encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
763   int iIdx = 0;
764 
765   while (iIdx <= p.numframes) {
766     EncodeOneFrame (1);
767     if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
768       ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
769     }
770     //decoding after each encoding frame
771     int len = 0;
772     encToDecData (info, len);
773     unsigned char* pData[3] = { NULL };
774     memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
775     if (iIdx < (int) strlen (p.pLossSequence)) {
776       switch (p.pLossSequence[iIdx]) {
777       case '0':
778         iTarDid = 0;
779         break;
780       case '1':
781         iTarDid = 1;
782         break;
783       case '2':
784         iTarDid = 2;
785         break;
786       case '3':
787         iTarDid = 3;
788         break;
789       default :
790         iTarDid = rand() % 4;
791         break;
792       }
793     } else {
794       iTarDid = rand() % 4;
795     }
796 
797     ExtractDidNal (&info, len, &m_SLostSim, iTarDid);
798     rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
799     int iTid = -1;
800     decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
801     ASSERT_EQ (iTid, -1);
802     m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
803     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, false);
804     rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
805     if (info.eFrameType == videoFrameTypeP && iIdx > 0 && iLastDid != iTarDid) {
806       ASSERT_NE (rv, 0);
807     } else if (info.eFrameType == videoFrameTypeIDR) {
808       ASSERT_EQ (rv, 0);
809     }
810     decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
811     ASSERT_EQ (iTid, info.sLayerInfo[0].uiTemporalId);
812     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, false);
813     LTRMarkFeedback (decoder_, encoder_, &m_LTR_Marking_Feedback, rv);
814     iIdx++;
815     iLastDid = iTarDid;
816   }
817 }
818 
819 
820