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