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, ¶m_);
21 param_.bEnableLongTermReference = true;
22 param_.iLTRRefNum = 1;
23 encoder_->Uninitialize();
24 int rv = encoder_->InitializeExt (¶m_);
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, ¶m_);
89 encoder_->Uninitialize();
90 int rv = encoder_->InitializeExt (¶m_);
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, ¶m_);
151 param_.iSpatialLayerNum = 1;
152 encoder_->Uninitialize();
153 int rv = encoder_->InitializeExt (¶m_);
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, ¶m_);
231
232 param_.iSpatialLayerNum = 1;
233 encoder_->Uninitialize();
234 int rv = encoder_->InitializeExt (¶m_);
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, ¶m_);
369 param_.iSpatialLayerNum = 1;
370 encoder_->Uninitialize();
371 int rv = encoder_->InitializeExt (¶m_);
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, ¶m_);
502 param_.iSpatialLayerNum = 1;
503 encoder_->Uninitialize();
504 int rv = encoder_->InitializeExt (¶m_);
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, ¶m_);
673 param_.iTemporalLayerNum = (rand() % 4) + 1;
674 param_.iSpatialLayerNum = 4;
675 encoder_->Uninitialize();
676 int rv = encoder_->InitializeExt (¶m_);
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, ¶m_);
740 param_.iTemporalLayerNum = (rand() % 4) + 1;
741 param_.iSpatialLayerNum = 4;
742 encoder_->Uninitialize();
743 int rv = encoder_->InitializeExt (¶m_);
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