1 /*
2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "modules/video_coding/decoding_state.h"
12 
13 #include "modules/rtp_rtcp/source/rtp_video_header.h"
14 #include "modules/video_coding/codecs/interface/common_constants.h"
15 #include "modules/video_coding/codecs/vp8/include/vp8_globals.h"
16 #include "modules/video_coding/codecs/vp9/include/vp9_globals.h"
17 #include "modules/video_coding/frame_buffer.h"
18 #include "modules/video_coding/include/video_coding.h"
19 #include "modules/video_coding/packet.h"
20 #include "modules/video_coding/session_info.h"
21 #include "test/gtest.h"
22 
23 namespace webrtc {
24 
TEST(TestDecodingState,Sanity)25 TEST(TestDecodingState, Sanity) {
26   VCMDecodingState dec_state;
27   dec_state.Reset();
28   EXPECT_TRUE(dec_state.in_initial_state());
29   EXPECT_TRUE(dec_state.full_sync());
30 }
31 
TEST(TestDecodingState,FrameContinuity)32 TEST(TestDecodingState, FrameContinuity) {
33   VCMDecodingState dec_state;
34   // Check that makes decision based on correct method.
35   VCMFrameBuffer frame;
36   VCMFrameBuffer frame_key;
37   VCMPacket packet;
38   packet.video_header.is_first_packet_in_frame = true;
39   packet.timestamp = 1;
40   packet.seqNum = 0xffff;
41   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
42   packet.video_header.codec = kVideoCodecVP8;
43   auto& vp8_header =
44       packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
45   vp8_header.pictureId = 0x007F;
46   FrameData frame_data;
47   frame_data.rtt_ms = 0;
48   frame_data.rolling_average_packets_per_frame = -1;
49   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
50   // Always start with a key frame.
51   dec_state.Reset();
52   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
53   packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
54   EXPECT_LE(0, frame_key.InsertPacket(packet, 0, frame_data));
55   EXPECT_TRUE(dec_state.ContinuousFrame(&frame_key));
56   dec_state.SetState(&frame);
57   frame.Reset();
58   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
59   // Use pictureId
60   packet.video_header.is_first_packet_in_frame = false;
61   vp8_header.pictureId = 0x0002;
62   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
63   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
64   frame.Reset();
65   vp8_header.pictureId = 0;
66   packet.seqNum = 10;
67   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
68   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
69 
70   // Use sequence numbers.
71   vp8_header.pictureId = kNoPictureId;
72   frame.Reset();
73   packet.seqNum = dec_state.sequence_num() - 1u;
74   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
75   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
76   frame.Reset();
77   packet.seqNum = dec_state.sequence_num() + 1u;
78   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
79   // Insert another packet to this frame
80   packet.seqNum++;
81   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
82   // Verify wrap.
83   EXPECT_LE(dec_state.sequence_num(), 0xffff);
84   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
85   dec_state.SetState(&frame);
86 
87   // Insert packet with temporal info.
88   dec_state.Reset();
89   frame.Reset();
90   vp8_header.tl0PicIdx = 0;
91   vp8_header.temporalIdx = 0;
92   vp8_header.pictureId = 0;
93   packet.seqNum = 1;
94   packet.timestamp = 1;
95   EXPECT_TRUE(dec_state.full_sync());
96   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
97   dec_state.SetState(&frame);
98   EXPECT_TRUE(dec_state.full_sync());
99   frame.Reset();
100   // 1 layer up - still good.
101   vp8_header.tl0PicIdx = 0;
102   vp8_header.temporalIdx = 1;
103   vp8_header.pictureId = 1;
104   packet.seqNum = 2;
105   packet.timestamp = 2;
106   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
107   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
108   dec_state.SetState(&frame);
109   EXPECT_TRUE(dec_state.full_sync());
110   frame.Reset();
111   // Lost non-base layer packet => should update sync parameter.
112   vp8_header.tl0PicIdx = 0;
113   vp8_header.temporalIdx = 3;
114   vp8_header.pictureId = 3;
115   packet.seqNum = 4;
116   packet.timestamp = 4;
117   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
118   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
119   // Now insert the next non-base layer (belonging to a next tl0PicId).
120   frame.Reset();
121   vp8_header.tl0PicIdx = 1;
122   vp8_header.temporalIdx = 2;
123   vp8_header.pictureId = 4;
124   packet.seqNum = 5;
125   packet.timestamp = 5;
126   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
127   // Checking continuity and not updating the state - this should not trigger
128   // an update of sync state.
129   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
130   EXPECT_TRUE(dec_state.full_sync());
131   // Next base layer (dropped interim non-base layers) - should update sync.
132   frame.Reset();
133   vp8_header.tl0PicIdx = 1;
134   vp8_header.temporalIdx = 0;
135   vp8_header.pictureId = 5;
136   packet.seqNum = 6;
137   packet.timestamp = 6;
138   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
139   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
140   dec_state.SetState(&frame);
141   EXPECT_FALSE(dec_state.full_sync());
142 
143   // Check wrap for temporal layers.
144   frame.Reset();
145   vp8_header.tl0PicIdx = 0x00FF;
146   vp8_header.temporalIdx = 0;
147   vp8_header.pictureId = 6;
148   packet.seqNum = 7;
149   packet.timestamp = 7;
150   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
151   dec_state.SetState(&frame);
152   EXPECT_FALSE(dec_state.full_sync());
153   frame.Reset();
154   vp8_header.tl0PicIdx = 0x0000;
155   vp8_header.temporalIdx = 0;
156   vp8_header.pictureId = 7;
157   packet.seqNum = 8;
158   packet.timestamp = 8;
159   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
160   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
161   // The current frame is not continuous
162   dec_state.SetState(&frame);
163   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
164 }
165 
TEST(TestDecodingState,UpdateOldPacket)166 TEST(TestDecodingState, UpdateOldPacket) {
167   VCMDecodingState dec_state;
168   // Update only if zero size and newer than previous.
169   // Should only update if the timeStamp match.
170   VCMFrameBuffer frame;
171   VCMPacket packet;
172   packet.timestamp = 1;
173   packet.seqNum = 1;
174   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
175   FrameData frame_data;
176   frame_data.rtt_ms = 0;
177   frame_data.rolling_average_packets_per_frame = -1;
178   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
179   dec_state.SetState(&frame);
180   EXPECT_EQ(dec_state.sequence_num(), 1);
181   // Insert an empty packet that does not belong to the same frame.
182   // => Sequence num should be the same.
183   packet.timestamp = 2;
184   dec_state.UpdateOldPacket(&packet);
185   EXPECT_EQ(dec_state.sequence_num(), 1);
186   // Now insert empty packet belonging to the same frame.
187   packet.timestamp = 1;
188   packet.seqNum = 2;
189   packet.video_header.frame_type = VideoFrameType::kEmptyFrame;
190   packet.sizeBytes = 0;
191   dec_state.UpdateOldPacket(&packet);
192   EXPECT_EQ(dec_state.sequence_num(), 2);
193   // Now insert delta packet belonging to the same frame.
194   packet.timestamp = 1;
195   packet.seqNum = 3;
196   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
197   packet.sizeBytes = 1400;
198   dec_state.UpdateOldPacket(&packet);
199   EXPECT_EQ(dec_state.sequence_num(), 3);
200   // Insert a packet belonging to an older timestamp - should not update the
201   // sequence number.
202   packet.timestamp = 0;
203   packet.seqNum = 4;
204   packet.video_header.frame_type = VideoFrameType::kEmptyFrame;
205   packet.sizeBytes = 0;
206   dec_state.UpdateOldPacket(&packet);
207   EXPECT_EQ(dec_state.sequence_num(), 3);
208 }
209 
TEST(TestDecodingState,MultiLayerBehavior)210 TEST(TestDecodingState, MultiLayerBehavior) {
211   // Identify sync/non-sync when more than one layer.
212   VCMDecodingState dec_state;
213   // Identify packets belonging to old frames/packets.
214   // Set state for current frames.
215   // tl0PicIdx 0, temporal id 0.
216   VCMFrameBuffer frame;
217   VCMPacket packet;
218   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
219   packet.video_header.codec = kVideoCodecVP8;
220   packet.timestamp = 0;
221   packet.seqNum = 0;
222   auto& vp8_header =
223       packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
224   vp8_header.tl0PicIdx = 0;
225   vp8_header.temporalIdx = 0;
226   vp8_header.pictureId = 0;
227   FrameData frame_data;
228   frame_data.rtt_ms = 0;
229   frame_data.rolling_average_packets_per_frame = -1;
230   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
231   dec_state.SetState(&frame);
232   // tl0PicIdx 0, temporal id 1.
233   frame.Reset();
234   packet.timestamp = 1;
235   packet.seqNum = 1;
236   vp8_header.tl0PicIdx = 0;
237   vp8_header.temporalIdx = 1;
238   vp8_header.pictureId = 1;
239   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
240   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
241   dec_state.SetState(&frame);
242   EXPECT_TRUE(dec_state.full_sync());
243   // Lost tl0PicIdx 0, temporal id 2.
244   // Insert tl0PicIdx 0, temporal id 3.
245   frame.Reset();
246   packet.timestamp = 3;
247   packet.seqNum = 3;
248   vp8_header.tl0PicIdx = 0;
249   vp8_header.temporalIdx = 3;
250   vp8_header.pictureId = 3;
251   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
252   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
253   dec_state.SetState(&frame);
254   EXPECT_FALSE(dec_state.full_sync());
255   // Insert next base layer
256   frame.Reset();
257   packet.timestamp = 4;
258   packet.seqNum = 4;
259   vp8_header.tl0PicIdx = 1;
260   vp8_header.temporalIdx = 0;
261   vp8_header.pictureId = 4;
262   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
263   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
264   dec_state.SetState(&frame);
265   EXPECT_FALSE(dec_state.full_sync());
266   // Insert key frame - should update sync value.
267   // A key frame is always a base layer.
268   frame.Reset();
269   packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
270   packet.video_header.is_first_packet_in_frame = true;
271   packet.timestamp = 5;
272   packet.seqNum = 5;
273   vp8_header.tl0PicIdx = 2;
274   vp8_header.temporalIdx = 0;
275   vp8_header.pictureId = 5;
276   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
277   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
278   dec_state.SetState(&frame);
279   EXPECT_TRUE(dec_state.full_sync());
280   // After sync, a continuous PictureId is required
281   // (continuous base layer is not enough )
282   frame.Reset();
283   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
284   packet.timestamp = 6;
285   packet.seqNum = 6;
286   vp8_header.tl0PicIdx = 3;
287   vp8_header.temporalIdx = 0;
288   vp8_header.pictureId = 6;
289   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
290   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
291   EXPECT_TRUE(dec_state.full_sync());
292   frame.Reset();
293   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
294   packet.video_header.is_first_packet_in_frame = true;
295   packet.timestamp = 8;
296   packet.seqNum = 8;
297   vp8_header.tl0PicIdx = 4;
298   vp8_header.temporalIdx = 0;
299   vp8_header.pictureId = 8;
300   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
301   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
302   EXPECT_TRUE(dec_state.full_sync());
303   dec_state.SetState(&frame);
304   EXPECT_FALSE(dec_state.full_sync());
305 
306   // Insert a non-ref frame - should update sync value.
307   frame.Reset();
308   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
309   packet.video_header.is_first_packet_in_frame = true;
310   packet.timestamp = 9;
311   packet.seqNum = 9;
312   vp8_header.tl0PicIdx = 4;
313   vp8_header.temporalIdx = 2;
314   vp8_header.pictureId = 9;
315   vp8_header.layerSync = true;
316   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
317   dec_state.SetState(&frame);
318   EXPECT_TRUE(dec_state.full_sync());
319 
320   // The following test will verify the sync flag behavior after a loss.
321   // Create the following pattern:
322   // Update base layer, lose packet 1 (sync flag on, layer 2), insert packet 3
323   // (sync flag on, layer 2) check continuity and sync flag after inserting
324   // packet 2 (sync flag on, layer 1).
325   // Base layer.
326   frame.Reset();
327   dec_state.Reset();
328   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
329   packet.video_header.is_first_packet_in_frame = true;
330   packet.markerBit = 1;
331   packet.timestamp = 0;
332   packet.seqNum = 0;
333   vp8_header.tl0PicIdx = 0;
334   vp8_header.temporalIdx = 0;
335   vp8_header.pictureId = 0;
336   vp8_header.layerSync = false;
337   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
338   dec_state.SetState(&frame);
339   EXPECT_TRUE(dec_state.full_sync());
340   // Layer 2 - 2 packets (insert one, lose one).
341   frame.Reset();
342   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
343   packet.video_header.is_first_packet_in_frame = true;
344   packet.markerBit = 0;
345   packet.timestamp = 1;
346   packet.seqNum = 1;
347   vp8_header.tl0PicIdx = 0;
348   vp8_header.temporalIdx = 2;
349   vp8_header.pictureId = 1;
350   vp8_header.layerSync = true;
351   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
352   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
353   // Layer 1
354   frame.Reset();
355   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
356   packet.video_header.is_first_packet_in_frame = true;
357   packet.markerBit = 1;
358   packet.timestamp = 2;
359   packet.seqNum = 3;
360   vp8_header.tl0PicIdx = 0;
361   vp8_header.temporalIdx = 1;
362   vp8_header.pictureId = 2;
363   vp8_header.layerSync = true;
364   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
365   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
366   EXPECT_TRUE(dec_state.full_sync());
367 }
368 
TEST(TestDecodingState,DiscontinuousPicIdContinuousSeqNum)369 TEST(TestDecodingState, DiscontinuousPicIdContinuousSeqNum) {
370   VCMDecodingState dec_state;
371   VCMFrameBuffer frame;
372   VCMPacket packet;
373   frame.Reset();
374   packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
375   packet.video_header.codec = kVideoCodecVP8;
376   packet.timestamp = 0;
377   packet.seqNum = 0;
378   auto& vp8_header =
379       packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
380   vp8_header.tl0PicIdx = 0;
381   vp8_header.temporalIdx = 0;
382   vp8_header.pictureId = 0;
383   FrameData frame_data;
384   frame_data.rtt_ms = 0;
385   frame_data.rolling_average_packets_per_frame = -1;
386   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
387   dec_state.SetState(&frame);
388   EXPECT_TRUE(dec_state.full_sync());
389 
390   // Continuous sequence number but discontinuous picture id. This implies a
391   // a loss and we have to fall back to only decoding the base layer.
392   frame.Reset();
393   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
394   packet.timestamp += 3000;
395   ++packet.seqNum;
396   vp8_header.temporalIdx = 1;
397   vp8_header.pictureId = 2;
398   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
399   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
400   dec_state.SetState(&frame);
401   EXPECT_FALSE(dec_state.full_sync());
402 }
403 
TEST(TestDecodingState,OldInput)404 TEST(TestDecodingState, OldInput) {
405   VCMDecodingState dec_state;
406   // Identify packets belonging to old frames/packets.
407   // Set state for current frames.
408   VCMFrameBuffer frame;
409   VCMPacket packet;
410   packet.timestamp = 10;
411   packet.seqNum = 1;
412   FrameData frame_data;
413   frame_data.rtt_ms = 0;
414   frame_data.rolling_average_packets_per_frame = -1;
415   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
416   dec_state.SetState(&frame);
417   packet.timestamp = 9;
418   EXPECT_TRUE(dec_state.IsOldPacket(&packet));
419   // Check for old frame
420   frame.Reset();
421   frame.InsertPacket(packet, 0, frame_data);
422   EXPECT_TRUE(dec_state.IsOldFrame(&frame));
423 }
424 
TEST(TestDecodingState,PictureIdRepeat)425 TEST(TestDecodingState, PictureIdRepeat) {
426   VCMDecodingState dec_state;
427   VCMFrameBuffer frame;
428   VCMPacket packet;
429   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
430   packet.video_header.codec = kVideoCodecVP8;
431   packet.timestamp = 0;
432   packet.seqNum = 0;
433   auto& vp8_header =
434       packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
435   vp8_header.tl0PicIdx = 0;
436   vp8_header.temporalIdx = 0;
437   vp8_header.pictureId = 0;
438   FrameData frame_data;
439   frame_data.rtt_ms = 0;
440   frame_data.rolling_average_packets_per_frame = -1;
441   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
442   dec_state.SetState(&frame);
443   // tl0PicIdx 0, temporal id 1.
444   frame.Reset();
445   ++packet.timestamp;
446   ++packet.seqNum;
447   vp8_header.temporalIdx++;
448   vp8_header.pictureId++;
449   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
450   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
451   frame.Reset();
452   // Testing only gap in tl0PicIdx when tl0PicIdx in continuous.
453   vp8_header.tl0PicIdx += 3;
454   vp8_header.temporalIdx++;
455   vp8_header.tl0PicIdx = 1;
456   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
457   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
458 }
459 
TEST(TestDecodingState,FrameContinuityFlexibleModeKeyFrame)460 TEST(TestDecodingState, FrameContinuityFlexibleModeKeyFrame) {
461   VCMDecodingState dec_state;
462   VCMFrameBuffer frame;
463   VCMPacket packet;
464   packet.video_header.is_first_packet_in_frame = true;
465   packet.timestamp = 1;
466   packet.seqNum = 0xffff;
467   uint8_t data[] = "I need a data pointer for this test!";
468   packet.sizeBytes = sizeof(data);
469   packet.dataPtr = data;
470   packet.video_header.codec = kVideoCodecVP9;
471 
472   auto& vp9_hdr =
473       packet.video_header.video_type_header.emplace<RTPVideoHeaderVP9>();
474   vp9_hdr.picture_id = 10;
475   vp9_hdr.flexible_mode = true;
476 
477   FrameData frame_data;
478   frame_data.rtt_ms = 0;
479   frame_data.rolling_average_packets_per_frame = -1;
480 
481   // Key frame as first frame
482   packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
483   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
484   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
485   dec_state.SetState(&frame);
486 
487   // Key frame again
488   vp9_hdr.picture_id = 11;
489   frame.Reset();
490   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
491   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
492   dec_state.SetState(&frame);
493 
494   // Ref to 11, continuous
495   frame.Reset();
496   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
497   vp9_hdr.picture_id = 12;
498   vp9_hdr.num_ref_pics = 1;
499   vp9_hdr.pid_diff[0] = 1;
500   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
501   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
502 }
503 
TEST(TestDecodingState,FrameContinuityFlexibleModeOutOfOrderFrames)504 TEST(TestDecodingState, FrameContinuityFlexibleModeOutOfOrderFrames) {
505   VCMDecodingState dec_state;
506   VCMFrameBuffer frame;
507   VCMPacket packet;
508   packet.video_header.is_first_packet_in_frame = true;
509   packet.timestamp = 1;
510   packet.seqNum = 0xffff;
511   uint8_t data[] = "I need a data pointer for this test!";
512   packet.sizeBytes = sizeof(data);
513   packet.dataPtr = data;
514   packet.video_header.codec = kVideoCodecVP9;
515 
516   auto& vp9_hdr =
517       packet.video_header.video_type_header.emplace<RTPVideoHeaderVP9>();
518   vp9_hdr.picture_id = 10;
519   vp9_hdr.flexible_mode = true;
520 
521   FrameData frame_data;
522   frame_data.rtt_ms = 0;
523   frame_data.rolling_average_packets_per_frame = -1;
524 
525   // Key frame as first frame
526   packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
527   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
528   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
529   dec_state.SetState(&frame);
530 
531   // Ref to 10, continuous
532   frame.Reset();
533   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
534   vp9_hdr.picture_id = 15;
535   vp9_hdr.num_ref_pics = 1;
536   vp9_hdr.pid_diff[0] = 5;
537   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
538   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
539   dec_state.SetState(&frame);
540 
541   // Out of order, last id 15, this id 12, ref to 10, continuous
542   frame.Reset();
543   vp9_hdr.picture_id = 12;
544   vp9_hdr.pid_diff[0] = 2;
545   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
546   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
547   dec_state.SetState(&frame);
548 
549   // Ref 10, 12, 15, continuous
550   frame.Reset();
551   vp9_hdr.picture_id = 20;
552   vp9_hdr.num_ref_pics = 3;
553   vp9_hdr.pid_diff[0] = 10;
554   vp9_hdr.pid_diff[1] = 8;
555   vp9_hdr.pid_diff[2] = 5;
556   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
557   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
558 }
559 
TEST(TestDecodingState,FrameContinuityFlexibleModeGeneral)560 TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
561   VCMDecodingState dec_state;
562   VCMFrameBuffer frame;
563   VCMPacket packet;
564   packet.video_header.is_first_packet_in_frame = true;
565   packet.timestamp = 1;
566   packet.seqNum = 0xffff;
567   uint8_t data[] = "I need a data pointer for this test!";
568   packet.sizeBytes = sizeof(data);
569   packet.dataPtr = data;
570   packet.video_header.codec = kVideoCodecVP9;
571 
572   auto& vp9_hdr =
573       packet.video_header.video_type_header.emplace<RTPVideoHeaderVP9>();
574   vp9_hdr.picture_id = 10;
575   vp9_hdr.flexible_mode = true;
576 
577   FrameData frame_data;
578   frame_data.rtt_ms = 0;
579   frame_data.rolling_average_packets_per_frame = -1;
580 
581   // Key frame as first frame
582   packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
583   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
584   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
585 
586   // Delta frame as first frame
587   frame.Reset();
588   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
589   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
590   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
591 
592   // Key frame then delta frame
593   frame.Reset();
594   packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
595   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
596   dec_state.SetState(&frame);
597   frame.Reset();
598   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
599   vp9_hdr.num_ref_pics = 1;
600   vp9_hdr.picture_id = 15;
601   vp9_hdr.pid_diff[0] = 5;
602   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
603   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
604   dec_state.SetState(&frame);
605 
606   // Ref to 11, not continuous
607   frame.Reset();
608   vp9_hdr.picture_id = 16;
609   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
610   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
611 
612   // Ref to 15, continuous
613   frame.Reset();
614   vp9_hdr.picture_id = 16;
615   vp9_hdr.pid_diff[0] = 1;
616   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
617   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
618   dec_state.SetState(&frame);
619 
620   // Ref to 11 and 15, not continuous
621   frame.Reset();
622   vp9_hdr.picture_id = 20;
623   vp9_hdr.num_ref_pics = 2;
624   vp9_hdr.pid_diff[0] = 9;
625   vp9_hdr.pid_diff[1] = 5;
626   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
627   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
628 
629   // Ref to 10, 15 and 16, continuous
630   frame.Reset();
631   vp9_hdr.picture_id = 22;
632   vp9_hdr.num_ref_pics = 3;
633   vp9_hdr.pid_diff[0] = 12;
634   vp9_hdr.pid_diff[1] = 7;
635   vp9_hdr.pid_diff[2] = 6;
636   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
637   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
638   dec_state.SetState(&frame);
639 
640   // Key Frame, continuous
641   frame.Reset();
642   packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
643   vp9_hdr.picture_id = VCMDecodingState::kFrameDecodedLength - 2;
644   vp9_hdr.num_ref_pics = 0;
645   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
646   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
647   dec_state.SetState(&frame);
648 
649   // Frame at last index, ref to KF, continuous
650   frame.Reset();
651   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
652   vp9_hdr.picture_id = VCMDecodingState::kFrameDecodedLength - 1;
653   vp9_hdr.num_ref_pics = 1;
654   vp9_hdr.pid_diff[0] = 1;
655   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
656   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
657   dec_state.SetState(&frame);
658 
659   // Frame after wrapping buffer length, ref to last index, continuous
660   frame.Reset();
661   vp9_hdr.picture_id = 0;
662   vp9_hdr.num_ref_pics = 1;
663   vp9_hdr.pid_diff[0] = 1;
664   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
665   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
666   dec_state.SetState(&frame);
667 
668   // Frame after wrapping start frame, ref to 0, continuous
669   frame.Reset();
670   vp9_hdr.picture_id = 20;
671   vp9_hdr.num_ref_pics = 1;
672   vp9_hdr.pid_diff[0] = 20;
673   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
674   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
675   dec_state.SetState(&frame);
676 
677   // Frame after wrapping start frame, ref to 10, not continuous
678   frame.Reset();
679   vp9_hdr.picture_id = 23;
680   vp9_hdr.num_ref_pics = 1;
681   vp9_hdr.pid_diff[0] = 13;
682   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
683   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
684 
685   // Key frame, continuous
686   frame.Reset();
687   packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
688   vp9_hdr.picture_id = 25;
689   vp9_hdr.num_ref_pics = 0;
690   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
691   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
692   dec_state.SetState(&frame);
693 
694   // Ref to KF, continuous
695   frame.Reset();
696   packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
697   vp9_hdr.picture_id = 26;
698   vp9_hdr.num_ref_pics = 1;
699   vp9_hdr.pid_diff[0] = 1;
700   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
701   EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
702   dec_state.SetState(&frame);
703 
704   // Ref to frame previous to KF, not continuous
705   frame.Reset();
706   vp9_hdr.picture_id = 30;
707   vp9_hdr.num_ref_pics = 1;
708   vp9_hdr.pid_diff[0] = 30;
709   EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
710   EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
711 }
712 
713 }  // namespace webrtc
714