blob: bef7f81c62aa8e2c4efc7c1462af97adb85af73d [file] [log] [blame]
mikhal@webrtc.org62665b82011-12-29 18:09:58 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/video_coding/decoding_state.h"
Jonas Olssona4d87372019-07-05 19:08:33 +020012
Yves Gerey3e707812018-11-28 16:47:49 +010013#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"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/video_coding/frame_buffer.h"
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "modules/video_coding/include/video_coding.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020019#include "modules/video_coding/packet.h"
Yves Gerey3e707812018-11-28 16:47:49 +010020#include "modules/video_coding/session_info.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020021#include "test/gtest.h"
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000022
23namespace webrtc {
24
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000025TEST(TestDecodingState, Sanity) {
26 VCMDecodingState dec_state;
27 dec_state.Reset();
stefan@webrtc.orga64300a2013-03-04 15:24:40 +000028 EXPECT_TRUE(dec_state.in_initial_state());
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000029 EXPECT_TRUE(dec_state.full_sync());
30}
31
32TEST(TestDecodingState, FrameContinuity) {
33 VCMDecodingState dec_state;
34 // Check that makes decision based on correct method.
andrew@webrtc.orgdf9c0e52013-04-24 02:13:18 +000035 VCMFrameBuffer frame;
mikhal@webrtc.org8392cd92013-04-25 21:30:50 +000036 VCMFrameBuffer frame_key;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +000037 VCMPacket packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +010038 packet.video_header.is_first_packet_in_frame = true;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +000039 packet.timestamp = 1;
40 packet.seqNum = 0xffff;
Niels Möllerabbc50e2019-04-24 09:41:16 +020041 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Niels Möller520ca4e2018-06-04 11:14:38 +020042 packet.video_header.codec = kVideoCodecVP8;
Philip Eliassond52a1a62018-09-07 13:03:55 +000043 auto& vp8_header =
44 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
45 vp8_header.pictureId = 0x007F;
agalusza@google.comd818dcb2013-07-29 21:48:11 +000046 FrameData frame_data;
47 frame_data.rtt_ms = 0;
48 frame_data.rolling_average_packets_per_frame = -1;
Niels Möller375b3462019-01-10 15:35:56 +010049 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org8392cd92013-04-25 21:30:50 +000050 // Always start with a key frame.
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000051 dec_state.Reset();
mikhal@webrtc.org8392cd92013-04-25 21:30:50 +000052 EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
Niels Möllerabbc50e2019-04-24 09:41:16 +020053 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möller375b3462019-01-10 15:35:56 +010054 EXPECT_LE(0, frame_key.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org8392cd92013-04-25 21:30:50 +000055 EXPECT_TRUE(dec_state.ContinuousFrame(&frame_key));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000056 dec_state.SetState(&frame);
57 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +020058 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000059 // Use pictureId
Niels Möllerd5e02f02019-02-20 13:12:21 +010060 packet.video_header.is_first_packet_in_frame = false;
Philip Eliassond52a1a62018-09-07 13:03:55 +000061 vp8_header.pictureId = 0x0002;
Niels Möller375b3462019-01-10 15:35:56 +010062 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000063 EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
64 frame.Reset();
Philip Eliassond52a1a62018-09-07 13:03:55 +000065 vp8_header.pictureId = 0;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +000066 packet.seqNum = 10;
Niels Möller375b3462019-01-10 15:35:56 +010067 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000068 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
69
70 // Use sequence numbers.
Philip Eliassond52a1a62018-09-07 13:03:55 +000071 vp8_header.pictureId = kNoPictureId;
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000072 frame.Reset();
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +000073 packet.seqNum = dec_state.sequence_num() - 1u;
Niels Möller375b3462019-01-10 15:35:56 +010074 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000075 EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
76 frame.Reset();
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +000077 packet.seqNum = dec_state.sequence_num() + 1u;
Niels Möller375b3462019-01-10 15:35:56 +010078 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000079 // Insert another packet to this frame
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +000080 packet.seqNum++;
Niels Möller375b3462019-01-10 15:35:56 +010081 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000082 // Verify wrap.
mikhal@webrtc.orgf31a47a2013-08-26 17:10:11 +000083 EXPECT_LE(dec_state.sequence_num(), 0xffff);
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000084 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();
Philip Eliassond52a1a62018-09-07 13:03:55 +000090 vp8_header.tl0PicIdx = 0;
91 vp8_header.temporalIdx = 0;
92 vp8_header.pictureId = 0;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +000093 packet.seqNum = 1;
94 packet.timestamp = 1;
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000095 EXPECT_TRUE(dec_state.full_sync());
Niels Möller375b3462019-01-10 15:35:56 +010096 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +000097 dec_state.SetState(&frame);
98 EXPECT_TRUE(dec_state.full_sync());
99 frame.Reset();
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000100 // 1 layer up - still good.
Philip Eliassond52a1a62018-09-07 13:03:55 +0000101 vp8_header.tl0PicIdx = 0;
102 vp8_header.temporalIdx = 1;
103 vp8_header.pictureId = 1;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000104 packet.seqNum = 2;
105 packet.timestamp = 2;
Niels Möller375b3462019-01-10 15:35:56 +0100106 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000107 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
108 dec_state.SetState(&frame);
109 EXPECT_TRUE(dec_state.full_sync());
110 frame.Reset();
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000111 // Lost non-base layer packet => should update sync parameter.
Philip Eliassond52a1a62018-09-07 13:03:55 +0000112 vp8_header.tl0PicIdx = 0;
113 vp8_header.temporalIdx = 3;
114 vp8_header.pictureId = 3;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000115 packet.seqNum = 4;
116 packet.timestamp = 4;
Niels Möller375b3462019-01-10 15:35:56 +0100117 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000118 EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
119 // Now insert the next non-base layer (belonging to a next tl0PicId).
120 frame.Reset();
Philip Eliassond52a1a62018-09-07 13:03:55 +0000121 vp8_header.tl0PicIdx = 1;
122 vp8_header.temporalIdx = 2;
123 vp8_header.pictureId = 4;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000124 packet.seqNum = 5;
125 packet.timestamp = 5;
Niels Möller375b3462019-01-10 15:35:56 +0100126 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000127 // 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();
Philip Eliassond52a1a62018-09-07 13:03:55 +0000133 vp8_header.tl0PicIdx = 1;
134 vp8_header.temporalIdx = 0;
135 vp8_header.pictureId = 5;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000136 packet.seqNum = 6;
137 packet.timestamp = 6;
Niels Möller375b3462019-01-10 15:35:56 +0100138 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000139 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();
Philip Eliassond52a1a62018-09-07 13:03:55 +0000145 vp8_header.tl0PicIdx = 0x00FF;
146 vp8_header.temporalIdx = 0;
147 vp8_header.pictureId = 6;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000148 packet.seqNum = 7;
149 packet.timestamp = 7;
Niels Möller375b3462019-01-10 15:35:56 +0100150 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000151 dec_state.SetState(&frame);
152 EXPECT_FALSE(dec_state.full_sync());
153 frame.Reset();
Philip Eliassond52a1a62018-09-07 13:03:55 +0000154 vp8_header.tl0PicIdx = 0x0000;
155 vp8_header.temporalIdx = 0;
156 vp8_header.pictureId = 7;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000157 packet.seqNum = 8;
158 packet.timestamp = 8;
Niels Möller375b3462019-01-10 15:35:56 +0100159 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000160 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));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000164}
165
mikhal@webrtc.org77c425b2012-01-03 20:35:25 +0000166TEST(TestDecodingState, UpdateOldPacket) {
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000167 VCMDecodingState dec_state;
168 // Update only if zero size and newer than previous.
169 // Should only update if the timeStamp match.
170 VCMFrameBuffer frame;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000171 VCMPacket packet;
172 packet.timestamp = 1;
173 packet.seqNum = 1;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200174 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000175 FrameData frame_data;
176 frame_data.rtt_ms = 0;
177 frame_data.rolling_average_packets_per_frame = -1;
Niels Möller375b3462019-01-10 15:35:56 +0100178 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000179 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.
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000183 packet.timestamp = 2;
184 dec_state.UpdateOldPacket(&packet);
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000185 EXPECT_EQ(dec_state.sequence_num(), 1);
186 // Now insert empty packet belonging to the same frame.
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000187 packet.timestamp = 1;
188 packet.seqNum = 2;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200189 packet.video_header.frame_type = VideoFrameType::kEmptyFrame;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000190 packet.sizeBytes = 0;
191 dec_state.UpdateOldPacket(&packet);
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000192 EXPECT_EQ(dec_state.sequence_num(), 2);
mikhal@webrtc.org77c425b2012-01-03 20:35:25 +0000193 // Now insert delta packet belonging to the same frame.
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000194 packet.timestamp = 1;
195 packet.seqNum = 3;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200196 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000197 packet.sizeBytes = 1400;
198 dec_state.UpdateOldPacket(&packet);
mikhal@webrtc.org77c425b2012-01-03 20:35:25 +0000199 EXPECT_EQ(dec_state.sequence_num(), 3);
200 // Insert a packet belonging to an older timestamp - should not update the
201 // sequence number.
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000202 packet.timestamp = 0;
203 packet.seqNum = 4;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200204 packet.video_header.frame_type = VideoFrameType::kEmptyFrame;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000205 packet.sizeBytes = 0;
206 dec_state.UpdateOldPacket(&packet);
mikhal@webrtc.org77c425b2012-01-03 20:35:25 +0000207 EXPECT_EQ(dec_state.sequence_num(), 3);
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000208}
209
210TEST(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;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000217 VCMPacket packet;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200218 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Niels Möller520ca4e2018-06-04 11:14:38 +0200219 packet.video_header.codec = kVideoCodecVP8;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000220 packet.timestamp = 0;
221 packet.seqNum = 0;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000222 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;
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000227 FrameData frame_data;
228 frame_data.rtt_ms = 0;
229 frame_data.rolling_average_packets_per_frame = -1;
Niels Möller375b3462019-01-10 15:35:56 +0100230 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000231 dec_state.SetState(&frame);
232 // tl0PicIdx 0, temporal id 1.
233 frame.Reset();
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000234 packet.timestamp = 1;
235 packet.seqNum = 1;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000236 vp8_header.tl0PicIdx = 0;
237 vp8_header.temporalIdx = 1;
238 vp8_header.pictureId = 1;
Niels Möller375b3462019-01-10 15:35:56 +0100239 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000240 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();
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000246 packet.timestamp = 3;
247 packet.seqNum = 3;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000248 vp8_header.tl0PicIdx = 0;
249 vp8_header.temporalIdx = 3;
250 vp8_header.pictureId = 3;
Niels Möller375b3462019-01-10 15:35:56 +0100251 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000252 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();
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000257 packet.timestamp = 4;
258 packet.seqNum = 4;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000259 vp8_header.tl0PicIdx = 1;
260 vp8_header.temporalIdx = 0;
261 vp8_header.pictureId = 4;
Niels Möller375b3462019-01-10 15:35:56 +0100262 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000263 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();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200269 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100270 packet.video_header.is_first_packet_in_frame = true;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000271 packet.timestamp = 5;
272 packet.seqNum = 5;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000273 vp8_header.tl0PicIdx = 2;
274 vp8_header.temporalIdx = 0;
275 vp8_header.pictureId = 5;
Niels Möller375b3462019-01-10 15:35:56 +0100276 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000277 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();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200283 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000284 packet.timestamp = 6;
285 packet.seqNum = 6;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000286 vp8_header.tl0PicIdx = 3;
287 vp8_header.temporalIdx = 0;
288 vp8_header.pictureId = 6;
Niels Möller375b3462019-01-10 15:35:56 +0100289 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000290 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
291 EXPECT_TRUE(dec_state.full_sync());
292 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200293 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100294 packet.video_header.is_first_packet_in_frame = true;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000295 packet.timestamp = 8;
296 packet.seqNum = 8;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000297 vp8_header.tl0PicIdx = 4;
298 vp8_header.temporalIdx = 0;
299 vp8_header.pictureId = 8;
Niels Möller375b3462019-01-10 15:35:56 +0100300 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000301 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();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200308 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100309 packet.video_header.is_first_packet_in_frame = true;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000310 packet.timestamp = 9;
311 packet.seqNum = 9;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000312 vp8_header.tl0PicIdx = 4;
313 vp8_header.temporalIdx = 2;
314 vp8_header.pictureId = 9;
315 vp8_header.layerSync = true;
Niels Möller375b3462019-01-10 15:35:56 +0100316 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000317 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();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200328 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100329 packet.video_header.is_first_packet_in_frame = true;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000330 packet.markerBit = 1;
331 packet.timestamp = 0;
332 packet.seqNum = 0;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000333 vp8_header.tl0PicIdx = 0;
334 vp8_header.temporalIdx = 0;
335 vp8_header.pictureId = 0;
336 vp8_header.layerSync = false;
Niels Möller375b3462019-01-10 15:35:56 +0100337 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000338 dec_state.SetState(&frame);
339 EXPECT_TRUE(dec_state.full_sync());
340 // Layer 2 - 2 packets (insert one, lose one).
341 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200342 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100343 packet.video_header.is_first_packet_in_frame = true;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000344 packet.markerBit = 0;
345 packet.timestamp = 1;
346 packet.seqNum = 1;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000347 vp8_header.tl0PicIdx = 0;
348 vp8_header.temporalIdx = 2;
349 vp8_header.pictureId = 1;
350 vp8_header.layerSync = true;
Niels Möller375b3462019-01-10 15:35:56 +0100351 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000352 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
353 // Layer 1
354 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200355 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100356 packet.video_header.is_first_packet_in_frame = true;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000357 packet.markerBit = 1;
358 packet.timestamp = 2;
359 packet.seqNum = 3;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000360 vp8_header.tl0PicIdx = 0;
361 vp8_header.temporalIdx = 1;
362 vp8_header.pictureId = 2;
363 vp8_header.layerSync = true;
Niels Möller375b3462019-01-10 15:35:56 +0100364 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000365 EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
366 EXPECT_TRUE(dec_state.full_sync());
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000367}
368
stefan@webrtc.orge72e9ee2012-09-19 11:08:05 +0000369TEST(TestDecodingState, DiscontinuousPicIdContinuousSeqNum) {
370 VCMDecodingState dec_state;
371 VCMFrameBuffer frame;
372 VCMPacket packet;
373 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200374 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möller520ca4e2018-06-04 11:14:38 +0200375 packet.video_header.codec = kVideoCodecVP8;
stefan@webrtc.orge72e9ee2012-09-19 11:08:05 +0000376 packet.timestamp = 0;
377 packet.seqNum = 0;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000378 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;
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000383 FrameData frame_data;
384 frame_data.rtt_ms = 0;
385 frame_data.rolling_average_packets_per_frame = -1;
Niels Möller375b3462019-01-10 15:35:56 +0100386 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
stefan@webrtc.orge72e9ee2012-09-19 11:08:05 +0000387 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();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200393 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
stefan@webrtc.orge72e9ee2012-09-19 11:08:05 +0000394 packet.timestamp += 3000;
395 ++packet.seqNum;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000396 vp8_header.temporalIdx = 1;
397 vp8_header.pictureId = 2;
Niels Möller375b3462019-01-10 15:35:56 +0100398 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
stefan@webrtc.orge72e9ee2012-09-19 11:08:05 +0000399 EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
400 dec_state.SetState(&frame);
401 EXPECT_FALSE(dec_state.full_sync());
402}
403
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000404TEST(TestDecodingState, OldInput) {
405 VCMDecodingState dec_state;
406 // Identify packets belonging to old frames/packets.
407 // Set state for current frames.
408 VCMFrameBuffer frame;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000409 VCMPacket packet;
410 packet.timestamp = 10;
411 packet.seqNum = 1;
agalusza@google.comd818dcb2013-07-29 21:48:11 +0000412 FrameData frame_data;
413 frame_data.rtt_ms = 0;
414 frame_data.rolling_average_packets_per_frame = -1;
Niels Möller375b3462019-01-10 15:35:56 +0100415 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000416 dec_state.SetState(&frame);
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000417 packet.timestamp = 9;
418 EXPECT_TRUE(dec_state.IsOldPacket(&packet));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000419 // Check for old frame
420 frame.Reset();
Niels Möller375b3462019-01-10 15:35:56 +0100421 frame.InsertPacket(packet, 0, frame_data);
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000422 EXPECT_TRUE(dec_state.IsOldFrame(&frame));
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000423}
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000424
425TEST(TestDecodingState, PictureIdRepeat) {
426 VCMDecodingState dec_state;
427 VCMFrameBuffer frame;
428 VCMPacket packet;
Niels Möllerabbc50e2019-04-24 09:41:16 +0200429 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Niels Möller520ca4e2018-06-04 11:14:38 +0200430 packet.video_header.codec = kVideoCodecVP8;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000431 packet.timestamp = 0;
432 packet.seqNum = 0;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000433 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;
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000438 FrameData frame_data;
439 frame_data.rtt_ms = 0;
440 frame_data.rolling_average_packets_per_frame = -1;
Niels Möller375b3462019-01-10 15:35:56 +0100441 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000442 dec_state.SetState(&frame);
443 // tl0PicIdx 0, temporal id 1.
444 frame.Reset();
445 ++packet.timestamp;
446 ++packet.seqNum;
Philip Eliassond52a1a62018-09-07 13:03:55 +0000447 vp8_header.temporalIdx++;
448 vp8_header.pictureId++;
Niels Möller375b3462019-01-10 15:35:56 +0100449 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000450 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
451 frame.Reset();
452 // Testing only gap in tl0PicIdx when tl0PicIdx in continuous.
Philip Eliassond52a1a62018-09-07 13:03:55 +0000453 vp8_header.tl0PicIdx += 3;
454 vp8_header.temporalIdx++;
455 vp8_header.tl0PicIdx = 1;
Niels Möller375b3462019-01-10 15:35:56 +0100456 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
mikhal@webrtc.org0aeb22e2013-10-28 22:26:14 +0000457 EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
458}
459
philipelcfc319b2015-11-10 07:17:23 -0800460TEST(TestDecodingState, FrameContinuityFlexibleModeKeyFrame) {
461 VCMDecodingState dec_state;
462 VCMFrameBuffer frame;
463 VCMPacket packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100464 packet.video_header.is_first_packet_in_frame = true;
philipelcfc319b2015-11-10 07:17:23 -0800465 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;
Niels Möller520ca4e2018-06-04 11:14:38 +0200470 packet.video_header.codec = kVideoCodecVP9;
philipelcfc319b2015-11-10 07:17:23 -0800471
philipel29d88462018-08-08 14:26:00 +0200472 auto& vp9_hdr =
473 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP9>();
philipelcfc319b2015-11-10 07:17:23 -0800474 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
Niels Möllerabbc50e2019-04-24 09:41:16 +0200482 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möller375b3462019-01-10 15:35:56 +0100483 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800484 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();
Niels Möller375b3462019-01-10 15:35:56 +0100490 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800491 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
492 dec_state.SetState(&frame);
493
494 // Ref to 11, continuous
495 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200496 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
philipelcfc319b2015-11-10 07:17:23 -0800497 vp9_hdr.picture_id = 12;
498 vp9_hdr.num_ref_pics = 1;
499 vp9_hdr.pid_diff[0] = 1;
Niels Möller375b3462019-01-10 15:35:56 +0100500 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800501 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
502}
503
504TEST(TestDecodingState, FrameContinuityFlexibleModeOutOfOrderFrames) {
505 VCMDecodingState dec_state;
506 VCMFrameBuffer frame;
507 VCMPacket packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100508 packet.video_header.is_first_packet_in_frame = true;
philipelcfc319b2015-11-10 07:17:23 -0800509 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;
Niels Möller520ca4e2018-06-04 11:14:38 +0200514 packet.video_header.codec = kVideoCodecVP9;
philipelcfc319b2015-11-10 07:17:23 -0800515
philipel29d88462018-08-08 14:26:00 +0200516 auto& vp9_hdr =
517 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP9>();
philipelcfc319b2015-11-10 07:17:23 -0800518 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
Niels Möllerabbc50e2019-04-24 09:41:16 +0200526 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möller375b3462019-01-10 15:35:56 +0100527 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800528 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
529 dec_state.SetState(&frame);
530
531 // Ref to 10, continuous
532 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200533 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
philipelcfc319b2015-11-10 07:17:23 -0800534 vp9_hdr.picture_id = 15;
535 vp9_hdr.num_ref_pics = 1;
536 vp9_hdr.pid_diff[0] = 5;
Niels Möller375b3462019-01-10 15:35:56 +0100537 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800538 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;
Niels Möller375b3462019-01-10 15:35:56 +0100545 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800546 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;
Niels Möller375b3462019-01-10 15:35:56 +0100556 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800557 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
558}
559
560TEST(TestDecodingState, FrameContinuityFlexibleModeGeneral) {
561 VCMDecodingState dec_state;
562 VCMFrameBuffer frame;
563 VCMPacket packet;
Niels Möllerd5e02f02019-02-20 13:12:21 +0100564 packet.video_header.is_first_packet_in_frame = true;
philipelcfc319b2015-11-10 07:17:23 -0800565 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;
Niels Möller520ca4e2018-06-04 11:14:38 +0200570 packet.video_header.codec = kVideoCodecVP9;
philipelcfc319b2015-11-10 07:17:23 -0800571
philipel29d88462018-08-08 14:26:00 +0200572 auto& vp9_hdr =
573 packet.video_header.video_type_header.emplace<RTPVideoHeaderVP9>();
philipelcfc319b2015-11-10 07:17:23 -0800574 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
Niels Möllerabbc50e2019-04-24 09:41:16 +0200582 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möller375b3462019-01-10 15:35:56 +0100583 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800584 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
585
586 // Delta frame as first frame
587 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200588 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
Niels Möller375b3462019-01-10 15:35:56 +0100589 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800590 EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
591
592 // Key frame then delta frame
593 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200594 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
Niels Möller375b3462019-01-10 15:35:56 +0100595 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800596 dec_state.SetState(&frame);
597 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200598 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
philipelcfc319b2015-11-10 07:17:23 -0800599 vp9_hdr.num_ref_pics = 1;
600 vp9_hdr.picture_id = 15;
601 vp9_hdr.pid_diff[0] = 5;
Niels Möller375b3462019-01-10 15:35:56 +0100602 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800603 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;
Niels Möller375b3462019-01-10 15:35:56 +0100609 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800610 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;
Niels Möller375b3462019-01-10 15:35:56 +0100616 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800617 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;
Niels Möller375b3462019-01-10 15:35:56 +0100626 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800627 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;
Niels Möller375b3462019-01-10 15:35:56 +0100636 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800637 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
638 dec_state.SetState(&frame);
639
640 // Key Frame, continuous
641 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200642 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
philipelcfc319b2015-11-10 07:17:23 -0800643 vp9_hdr.picture_id = VCMDecodingState::kFrameDecodedLength - 2;
644 vp9_hdr.num_ref_pics = 0;
Niels Möller375b3462019-01-10 15:35:56 +0100645 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800646 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
647 dec_state.SetState(&frame);
648
649 // Frame at last index, ref to KF, continuous
650 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200651 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
philipelcfc319b2015-11-10 07:17:23 -0800652 vp9_hdr.picture_id = VCMDecodingState::kFrameDecodedLength - 1;
653 vp9_hdr.num_ref_pics = 1;
654 vp9_hdr.pid_diff[0] = 1;
Niels Möller375b3462019-01-10 15:35:56 +0100655 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800656 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;
Niels Möller375b3462019-01-10 15:35:56 +0100664 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800665 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;
Niels Möller375b3462019-01-10 15:35:56 +0100673 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800674 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;
Niels Möller375b3462019-01-10 15:35:56 +0100682 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800683 EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
684
685 // Key frame, continuous
686 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200687 packet.video_header.frame_type = VideoFrameType::kVideoFrameKey;
philipelcfc319b2015-11-10 07:17:23 -0800688 vp9_hdr.picture_id = 25;
689 vp9_hdr.num_ref_pics = 0;
Niels Möller375b3462019-01-10 15:35:56 +0100690 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800691 EXPECT_TRUE(dec_state.ContinuousFrame(&frame));
692 dec_state.SetState(&frame);
693
694 // Ref to KF, continuous
695 frame.Reset();
Niels Möllerabbc50e2019-04-24 09:41:16 +0200696 packet.video_header.frame_type = VideoFrameType::kVideoFrameDelta;
philipelcfc319b2015-11-10 07:17:23 -0800697 vp9_hdr.picture_id = 26;
698 vp9_hdr.num_ref_pics = 1;
699 vp9_hdr.pid_diff[0] = 1;
Niels Möller375b3462019-01-10 15:35:56 +0100700 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800701 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;
Niels Möller375b3462019-01-10 15:35:56 +0100709 EXPECT_LE(0, frame.InsertPacket(packet, 0, frame_data));
philipelcfc319b2015-11-10 07:17:23 -0800710 EXPECT_FALSE(dec_state.ContinuousFrame(&frame));
711}
712
mikhal@webrtc.org62665b82011-12-29 18:09:58 +0000713} // namespace webrtc