• 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       //EC_IDC should not change till now
199       decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
200       EXPECT_EQ (uiGet, uiEcIdc);
201       //Set again inside
202       uiEcIdc = (ERROR_CON_IDC) (rand() % 2);
203       decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
204       decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
205       EXPECT_EQ (uiGet, uiEcIdc);
206 
207       rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
208       //EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
209       if (uiEcIdc == ERROR_CON_DISABLE && rv != 0)
210         EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
211 
212       //deal with next slice
213       iTotalSliceSize += len;
214       iPacketNum++;
215     } //while slice
216     iIdx++;
217   } //while frame
218 }
219 
220 //This case contain 1 slice per picture
221 //coding order:                 0   1   2   3   4   5   6   7
222 //frame type:                   IDR P   P   P   P   P   P   P
223 //EC_IDC:                       0   0   0   2   0   0   1   1
224 //loss:                         N   Y   N   N   N   Y   Y   N
225 
TEST_F(EncodeDecodeTestAPI,SetOptionECIDC_SpecificFrameChange)226 TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificFrameChange) {
227   uint32_t uiEcIdc;
228   uint32_t uiGet;
229   EncodeDecodeFileParamBase p = kFileParamArray[0];
230   prepareParamDefault (1, p.slicenum,  p.width, p.height, p.frameRate, &param_);
231 
232   param_.iSpatialLayerNum = 1;
233   encoder_->Uninitialize();
234   int rv = encoder_->InitializeExt (&param_);
235   ASSERT_TRUE (rv == cmResultSuccess);
236   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
237   EXPECT_EQ (uiGet, (ERROR_CON_IDC) ERROR_CON_SLICE_COPY); //default value should be ERROR_CON_SLICE_COPY
238   int32_t iTraceLevel = WELS_LOG_QUIET;
239   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
240   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
241 
242   //set EC=DISABLE
243   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
244   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
245   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
246   EXPECT_EQ (uiGet, uiEcIdc);
247 
248   //Start for enc/dec
249   int iIdx = 0;
250   int len = 0;
251   unsigned char* pData[3] = { NULL };
252   ASSERT_TRUE (InitialEncDec (p.width, p.height));
253   //Frame 0: IDR, EC_IDC=DISABLE, loss = 0
254   EncodeOneFrame (1);
255   encToDecData (info, len);
256   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
257   EXPECT_EQ (uiGet, (ERROR_CON_IDC) ERROR_CON_DISABLE);
258   pData[0] = pData[1] = pData[2] = 0;
259   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
260   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
261   EXPECT_EQ (rv, 0);
262   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
263   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
264   EXPECT_EQ (rv, 0);
265   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1);
266   iIdx++;
267 
268   //Frame 1: P, EC_IDC=DISABLE, loss = 1
269   EncodeOneFrame (1);
270   iIdx++;
271 
272   //Frame 2: P, EC_IDC=DISABLE, loss = 0
273   EncodeOneFrame (1);
274   encToDecData (info, len);
275   pData[0] = pData[1] = pData[2] = 0;
276   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
277   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
278   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
279   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
280   EXPECT_EQ (rv, 0); //parse correct
281   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output
282   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
283   EXPECT_TRUE (rv != 0); //construction error due to data loss
284   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output due to EC DISABLE
285   iIdx++;
286 
287   //set EC=SLICE_COPY
288   uiEcIdc = (uint32_t) (ERROR_CON_SLICE_COPY);
289   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
290   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
291   EXPECT_EQ (uiGet, uiEcIdc);
292   //Frame 3: P, EC_IDC=SLICE_COPY, loss = 0
293   EncodeOneFrame (1);
294   encToDecData (info, len);
295   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
296   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY);
297   pData[0] = pData[1] = pData[2] = 0;
298   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
299   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
300   EXPECT_EQ (rv, 0); //parse correct
301   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output
302   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
303   EXPECT_TRUE (rv != 0); //construction error due to data loss
304   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1);
305   iIdx++;
306 
307   //set EC=DISABLE
308   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
309   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
310   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
311   EXPECT_EQ (uiGet, uiEcIdc);
312   //Frame 4: P, EC_IDC=DISABLE, loss = 0
313   EncodeOneFrame (1);
314   encToDecData (info, len);
315   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
316   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
317   pData[0] = pData[1] = pData[2] = 0;
318   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
319   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
320   EXPECT_EQ (rv, 0); //parse correct
321   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output
322   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
323   //Ref picture is ECed, so current status is ECed, when EC disable, NO output
324   EXPECT_TRUE (rv != 0);
325   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
326   iIdx++;
327 
328   //Frame 5: P, EC_IDC=DISABLE, loss = 1
329   EncodeOneFrame (1);
330   iIdx++;
331 
332   //set EC=FRAME_COPY
333   uiEcIdc = (uint32_t) (ERROR_CON_FRAME_COPY);
334   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
335   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
336   EXPECT_EQ (uiGet, uiEcIdc);
337   //Frame 6: P, EC_IDC=FRAME_COPY, loss = 1
338   EncodeOneFrame (1);
339   EXPECT_EQ (uiGet, uiEcIdc);
340   iIdx++;
341 
342   //Frame 7: P, EC_IDC=FRAME_COPY, loss = 0
343   EncodeOneFrame (1);
344   encToDecData (info, len);
345   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
346   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_FRAME_COPY);
347   pData[0] = pData[1] = pData[2] = 0;
348   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
349   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
350   EXPECT_TRUE (rv == 0); // Now the parse process is Error_None, and the reconstruction will has error return
351   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //no output
352   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
353   EXPECT_TRUE (rv != 0); //not sure if previous data drop would be detected in construction
354   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1);
355   iIdx++;
356 }
357 
358 //This case contain 2 slices per picture for IDR loss
359 //coding order:                 0   1   2   3   4
360 //frame type                    IDR P   P   P   P
361 //EC_IDC                        2   2   0   1   0
362 //loss (2 slice: 1,2):          2   0   0   1   0
363 
TEST_F(EncodeDecodeTestAPI,SetOptionECIDC_SpecificSliceChange_IDRLoss)364 TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRLoss) {
365   uint32_t uiEcIdc = 2; //default set as SLICE_COPY
366   uint32_t uiGet;
367   EncodeDecodeFileParamBase p = kFileParamArray[0];
368   prepareParamDefault (1, 2,  p.width, p.height, p.frameRate, &param_);
369   param_.iSpatialLayerNum = 1;
370   encoder_->Uninitialize();
371   int rv = encoder_->InitializeExt (&param_);
372   ASSERT_TRUE (rv == cmResultSuccess);
373   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
374   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
375   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY); //default value should be ERROR_CON_SLICE_COPY
376   int32_t iTraceLevel = WELS_LOG_QUIET;
377   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
378   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
379 
380   //Start for enc/dec
381   int iIdx = 0;
382   int len = 0;
383   unsigned char* pData[3] = { NULL };
384   int iTotalSliceSize = 0;
385 
386   ASSERT_TRUE (InitialEncDec (p.width, p.height));
387 
388   //Frame 0: IDR, EC_IDC=2, loss = 2
389   EncodeOneFrame (1);
390   iTotalSliceSize = 0;
391   encToDecSliceData (0, 0, info, len); //SPS
392   iTotalSliceSize = len;
393   encToDecSliceData (0, 1, info, len); //PPS
394   iTotalSliceSize += len;
395   encToDecSliceData (1, 0, info, len); //first slice
396   iTotalSliceSize += len;
397   //second slice loss
398   pData[0] = pData[1] = pData[2] = 0;
399   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
400   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
401   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY);
402   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, iTotalSliceSize, pData, &dstBufInfo_);
403   EXPECT_EQ (rv, 0); //parse correct
404   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
405   EXPECT_EQ (rv, 0); // Reconstruct first slice OK
406   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //slice incomplete, no output
407   iIdx++;
408 
409   //Frame 1: P, EC_IDC=2, loss = 0
410   //will clean SPS/PPS status
411   EncodeOneFrame (1);
412   encToDecData (info, len); //all slice together
413   pData[0] = pData[1] = pData[2] = 0;
414   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
415   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
416   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY);
417   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
418   EXPECT_TRUE ((rv & 32) != 0); //parse correct, but reconstruct ECed
419   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //ECed output for frame 0
420   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //ECed status, reconstruction current frame 1
421   EXPECT_TRUE ((rv & 32) != 0); //decoder ECed status
422   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //ECed output for frame 1
423   iIdx++;
424 
425   //set EC=DISABLE
426   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
427   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
428   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
429   EXPECT_EQ (uiGet, uiEcIdc);
430   //Frame 2: P, EC_IDC=0, loss = 0
431   /////will clean SPS/PPS status
432   EncodeOneFrame (1);
433   encToDecData (info, len); //all slice together
434   pData[0] = pData[1] = pData[2] = 0;
435   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
436   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
437   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
438   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
439   EXPECT_EQ (rv, 0); //parse correct
440   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
441   // Ref picture is ECed, so reconstructed picture is ECed
442   EXPECT_TRUE ((rv & 32) != 0);
443   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
444   iIdx++;
445 
446   //set EC=SLICE_COPY
447   uiEcIdc = (uint32_t) (ERROR_CON_FRAME_COPY);
448   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
449   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
450   EXPECT_EQ (uiGet, uiEcIdc);
451   //Frame 3: P, EC_IDC=2, loss = 1
452   EncodeOneFrame (1);
453   encToDecSliceData (0, 0, info, iTotalSliceSize); //slice 1 lost
454   encToDecSliceData (0, 1, info, len); //slice 2
455   pData[0] = pData[1] = pData[2] = 0;
456   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
457   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
458   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_FRAME_COPY);
459   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf + iTotalSliceSize, len, pData, &dstBufInfo_);
460   EXPECT_EQ (rv, 0); //parse correct
461   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
462   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
463   EXPECT_TRUE ((rv & 32) != 0);
464   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //slice loss
465   iIdx++;
466 
467   //set EC=DISABLE
468   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
469   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
470   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
471   EXPECT_EQ (uiGet, uiEcIdc);
472   //Frame 4: P, EC_IDC=0, loss = 0
473   EncodeOneFrame (1);
474   encToDecData (info, len); //all slice
475   pData[0] = pData[1] = pData[2] = 0;
476   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
477   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
478   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
479   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
480   EXPECT_TRUE (rv != 0);
481   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); // EC_IDC=0, previous picture slice lost, no output
482   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
483   EXPECT_TRUE (rv != 0);
484   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); // No ref picture, no output
485   iIdx++;
486 
487 }
488 
489 
490 
491 //This case contain 2 slices per picture for no IDR loss
492 //coding order:                 0   1   2   3   4   5
493 //frame type                    IDR P   P   P   P   IDR
494 //EC_IDC                        0   2   0   2   0   ^2^
495 //loss (2 slice: 1,2):          0   0   1   2   0   0
496 
TEST_F(EncodeDecodeTestAPI,SetOptionECIDC_SpecificSliceChange_IDRNoLoss)497 TEST_F (EncodeDecodeTestAPI, SetOptionECIDC_SpecificSliceChange_IDRNoLoss) {
498   uint32_t uiEcIdc;
499   uint32_t uiGet;
500   EncodeDecodeFileParamBase p = kFileParamArray[0];
501   prepareParamDefault (1, 2,  p.width, p.height, p.frameRate, &param_);
502   param_.iSpatialLayerNum = 1;
503   encoder_->Uninitialize();
504   int rv = encoder_->InitializeExt (&param_);
505   ASSERT_TRUE (rv == cmResultSuccess);
506   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
507   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY); //default value should be ERROR_CON_SLICE_COPY
508   int32_t iTraceLevel = WELS_LOG_QUIET;
509   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
510   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
511 
512   //Start for enc/dec
513   int iIdx = 0;
514   int len = 0;
515   unsigned char* pData[3] = { NULL };
516   int iTotalSliceSize = 0;
517 
518   ASSERT_TRUE (InitialEncDec (p.width, p.height));
519 
520   //set EC=DISABLE
521   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
522   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
523   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
524   EXPECT_EQ (uiGet, uiEcIdc);
525   //Frame 0: IDR, EC_IDC=0, loss = 0
526   //Expected result: all OK, 2nd Output
527   EncodeOneFrame (1);
528   encToDecData (info, len); //all slice
529   pData[0] = pData[1] = pData[2] = 0;
530   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
531   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
532   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
533   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
534   EXPECT_EQ (rv, 0); //parse correct
535   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
536   EXPECT_EQ (rv, 0); //parse correct
537   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //output frame 0
538   iIdx++;
539 
540   //Frame 1: P, EC_IDC=0, loss = 0
541   //Expected result: all OK, 2nd Output
542   EncodeOneFrame (1);
543   encToDecData (info, len); //all slice together
544   pData[0] = pData[1] = pData[2] = 0;
545   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
546   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
547   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
548   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
549   EXPECT_EQ (rv, 0); //parse correct
550   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //ECed output for frame 0
551   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction current frame 1
552   EXPECT_EQ (rv, 0); //parse correct
553   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //ECed output for frame 1
554   iIdx++;
555 
556   //Frame 2: P, EC_IDC=0, loss = 1
557   //Expected result: all OK, no Output
558   EncodeOneFrame (1);
559   encToDecSliceData (0, 0, info, iTotalSliceSize); // slice 1 lost
560   encToDecSliceData (0, 1, info, len); // slice 2 only
561   pData[0] = pData[1] = pData[2] = 0;
562   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
563   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
564   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
565   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf + iTotalSliceSize, len, pData, &dstBufInfo_);
566   EXPECT_EQ (rv, 0); //parse correct
567   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
568   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
569   EXPECT_EQ (rv, 0); //parse correct
570   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0);
571   iIdx++;
572 
573   //set EC=SLICE_COPY
574   uiEcIdc = (uint32_t) (ERROR_CON_SLICE_COPY);
575   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
576   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
577   EXPECT_EQ (uiGet, uiEcIdc);
578   //Frame 3: P, EC_IDC=2, loss = 2
579   //Expected result: neither OK, 1st Output
580   EncodeOneFrame (1);
581   encToDecSliceData (0, 0, info, len); //slice 1 only
582   pData[0] = pData[1] = pData[2] = 0;
583   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
584   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
585   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_SLICE_COPY);
586   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
587   EXPECT_TRUE ((rv & 32) != 0); //parse OK but frame 2 ECed
588   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //slice loss but ECed output Frame 2
589   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
590   EXPECT_TRUE ((rv & 32) != 0);
591   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //slice loss
592   iIdx++;
593 
594   //set EC=DISABLE
595   uiEcIdc = (uint32_t) (ERROR_CON_DISABLE);
596   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
597   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
598   EXPECT_EQ (uiGet, uiEcIdc);
599   //Frame 4: P, EC_IDC=0, loss = 0
600   //Expected result: depends on DecodeFrame2 result. If OK, output; else ,no output
601   EncodeOneFrame (1);
602   encToDecData (info, len); //all slice
603   pData[0] = pData[1] = pData[2] = 0;
604   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
605   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
606   EXPECT_EQ (uiGet, (uint32_t) ERROR_CON_DISABLE);
607   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
608   EXPECT_TRUE (rv != 0); //previous slice not outputted, will return error due to incomplete frame
609   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
610   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction,
611   // previous frame NOT output, no ref
612   EXPECT_TRUE (rv != 0);
613   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
614   iIdx++;
615 
616   //Frame 5: IDR, EC_IDC=2->0, loss = 0
617   //Expected result: depends on DecodeFrame2 result. If OK, output; else ,no output
618   int32_t iIDRPeriod = 1;
619   encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
620   EncodeOneFrame (1);
621   EXPECT_TRUE (info.eFrameType == videoFrameTypeIDR);
622   encToDecSliceData (0, 0, info, len); //SPS
623   iTotalSliceSize = len;
624   encToDecSliceData (0, 1, info, len); //PPS
625   iTotalSliceSize += len;
626   encToDecSliceData (1, 0, info, len); //slice 1
627   iTotalSliceSize += len;
628   //set EC=SLICE_COPY for slice 1
629   uiEcIdc = (uint32_t) (ERROR_CON_SLICE_COPY);
630   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
631   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
632   EXPECT_EQ (uiGet, uiEcIdc);
633   pData[0] = pData[1] = pData[2] = 0;
634   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
635   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, iTotalSliceSize, pData, &dstBufInfo_);
636   EXPECT_TRUE (rv == 0); // IDR status return error_free
637   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //frame incomplete
638   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction,
639   EXPECT_TRUE (rv == 0);
640   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //output previous pic
641   //set EC=DISABLE for slice 2
642   encToDecSliceData (1, 1, info, len); //slice 1
643   uiEcIdc = (int) (ERROR_CON_DISABLE);
644   decoder_->SetOption (DECODER_OPTION_ERROR_CON_IDC, &uiEcIdc);
645   decoder_->GetOption (DECODER_OPTION_ERROR_CON_IDC, &uiGet);
646   EXPECT_EQ (uiGet, uiEcIdc);
647   pData[0] = pData[1] = pData[2] = 0;
648   memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
649   rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf + iTotalSliceSize, len, pData, &dstBufInfo_);
650   EXPECT_EQ (rv, 0); //Parse correct under no EC
651   EXPECT_EQ (dstBufInfo_.iBufferStatus, 0); //frame incomplete
652   rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction,
653   EXPECT_EQ (rv, 0);
654   EXPECT_EQ (dstBufInfo_.iBufferStatus, 1); //output previous pic
655   iIdx++;
656 
657 }
658 
659 static const EncodeDecodeFileParamBase kSVCSwitch[] = {
660   {300, 160, 96, 6.0f, 2, 1, "120012130101012311201221323"},
661 };
662 
TEST_F(EncodeDecodeTestAPI,Engine_SVC_Switch_I)663 TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_I) {
664   SLTRMarkingFeedback m_LTR_Marking_Feedback;
665   SLTRRecoverRequest m_LTR_Recover_Request;
666   m_LTR_Recover_Request.uiIDRPicId = 0;
667   m_LTR_Recover_Request.iLayerId = 0;
668   m_LTR_Marking_Feedback.iLayerId = 0;
669   EncodeDecodeFileParamBase p = kSVCSwitch[0];
670   p.width = p.width << 2;
671   p.height = p.height << 2;
672   prepareParamDefault (4, p.slicenum, p.width, p.height, p.frameRate, &param_);
673   param_.iTemporalLayerNum = (rand() % 4) + 1;
674   param_.iSpatialLayerNum = 4;
675   encoder_->Uninitialize();
676   int rv = encoder_->InitializeExt (&param_);
677   ASSERT_TRUE (rv == cmResultSuccess);
678   m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
679 
680   ASSERT_TRUE (InitialEncDec (p.width, p.height));
681   int32_t iTraceLevel = WELS_LOG_QUIET;
682   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
683   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
684   int32_t iSpsPpsIdAddition = 1;
685   encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
686   int32_t iIDRPeriod = (int32_t) pow (2.0f, (param_.iTemporalLayerNum - 1)) * ((rand() % 5) + 1);
687   encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
688   SLTRConfig sLtrConfigVal;
689   sLtrConfigVal.bEnableLongTermReference = 1;
690   sLtrConfigVal.iLTRRefNum = 1;
691   encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
692   int32_t iLtrPeriod = 2;
693   encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
694   int iIdx = 0;
695   int iTarDid = 0;
696   while (iIdx <= p.numframes) {
697     EncodeOneFrame (1);
698     if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
699       ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
700     }
701     if (info.eFrameType == videoFrameTypeIDR) {
702       iTarDid = rand() % 4;
703     }
704     //decoding after each encoding frame
705     int len = 0;
706     encToDecData (info, len);
707     unsigned char* pData[3] = { NULL };
708     memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
709 
710     ExtractDidNal (&info, len, &m_SLostSim, iTarDid);
711     rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
712     ASSERT_EQ (rv, 0);
713     int iTid = -1;
714     decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
715     ASSERT_EQ (iTid, -1);
716     m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
717     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
718     rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
719     ASSERT_EQ (rv, 0);
720     decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
721     ASSERT_EQ (iTid, info.sLayerInfo[0].uiTemporalId);
722     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, true);
723     LTRMarkFeedback (decoder_, encoder_, &m_LTR_Marking_Feedback, rv);
724     iIdx++;
725   }
726 }
727 
TEST_F(EncodeDecodeTestAPI,Engine_SVC_Switch_P)728 TEST_F (EncodeDecodeTestAPI, Engine_SVC_Switch_P) {
729   SLTRMarkingFeedback m_LTR_Marking_Feedback;
730   SLTRRecoverRequest m_LTR_Recover_Request;
731   m_LTR_Recover_Request.uiIDRPicId = 0;
732   m_LTR_Recover_Request.iLayerId = 0;
733   m_LTR_Marking_Feedback.iLayerId = 0;
734   EncodeDecodeFileParamBase p = kSVCSwitch[0];
735   int iTarDid = 0;
736   int iLastDid = 0;
737   p.width = p.width << 2;
738   p.height = p.height << 2;
739   prepareParamDefault (4, p.slicenum, p.width, p.height, p.frameRate, &param_);
740   param_.iTemporalLayerNum = (rand() % 4) + 1;
741   param_.iSpatialLayerNum = 4;
742   encoder_->Uninitialize();
743   int rv = encoder_->InitializeExt (&param_);
744   ASSERT_TRUE (rv == cmResultSuccess);
745   m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
746 
747   ASSERT_TRUE (InitialEncDec (p.width, p.height));
748   int32_t iTraceLevel = WELS_LOG_QUIET;
749   encoder_->SetOption (ENCODER_OPTION_TRACE_LEVEL, &iTraceLevel);
750   decoder_->SetOption (DECODER_OPTION_TRACE_LEVEL, &iTraceLevel);
751   int32_t iSpsPpsIdAddition = 1;
752   encoder_->SetOption (ENCODER_OPTION_SPS_PPS_ID_STRATEGY, &iSpsPpsIdAddition);
753   int32_t iIDRPeriod = 60;
754   encoder_->SetOption (ENCODER_OPTION_IDR_INTERVAL, &iIDRPeriod);
755   SLTRConfig sLtrConfigVal;
756   sLtrConfigVal.bEnableLongTermReference = 1;
757   sLtrConfigVal.iLTRRefNum = 1;
758   encoder_->SetOption (ENCODER_OPTION_LTR, &sLtrConfigVal);
759   int32_t iLtrPeriod = 2;
760   encoder_->SetOption (ENCODER_LTR_MARKING_PERIOD, &iLtrPeriod);
761   int iIdx = 0;
762 
763   while (iIdx <= p.numframes) {
764     EncodeOneFrame (1);
765     if (m_LTR_Recover_Request.uiFeedbackType == IDR_RECOVERY_REQUEST) {
766       ASSERT_TRUE (info.eFrameType == videoFrameTypeIDR);
767     }
768     //decoding after each encoding frame
769     int len = 0;
770     encToDecData (info, len);
771     unsigned char* pData[3] = { NULL };
772     memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
773     if (iIdx < (int) strlen (p.pLossSequence)) {
774       switch (p.pLossSequence[iIdx]) {
775       case '0':
776         iTarDid = 0;
777         break;
778       case '1':
779         iTarDid = 1;
780         break;
781       case '2':
782         iTarDid = 2;
783         break;
784       case '3':
785         iTarDid = 3;
786         break;
787       default :
788         iTarDid = rand() % 4;
789         break;
790       }
791     } else {
792       iTarDid = rand() % 4;
793     }
794 
795     ExtractDidNal (&info, len, &m_SLostSim, iTarDid);
796     rv = decoder_->DecodeFrame2 (info.sLayerInfo[0].pBsBuf, len, pData, &dstBufInfo_);
797     int iTid = -1;
798     decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
799     ASSERT_EQ (iTid, -1);
800     m_LTR_Recover_Request.uiFeedbackType = NO_RECOVERY_REQUSET;
801     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, false);
802     rv = decoder_->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_); //reconstruction
803     if (info.eFrameType == videoFrameTypeP && iIdx > 0 && iLastDid != iTarDid) {
804       ASSERT_NE (rv, 0);
805     } else if (info.eFrameType == videoFrameTypeIDR) {
806       ASSERT_EQ (rv, 0);
807     }
808     decoder_->GetOption (DECODER_OPTION_TEMPORAL_ID, &iTid);
809     ASSERT_EQ (iTid, info.sLayerInfo[0].uiTemporalId);
810     LTRRecoveryRequest (decoder_, encoder_, &m_LTR_Recover_Request, rv, false);
811     LTRMarkFeedback (decoder_, encoder_, &m_LTR_Marking_Feedback, rv);
812     iIdx++;
813     iLastDid = iTarDid;
814   }
815 }
816 
817 
818