1 /*
2 * Copyright (c) 2021 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 #include "api/video/frame_buffer.h"
11
12 #include <vector>
13
14 #include "api/video/encoded_frame.h"
15 #include "test/fake_encoded_frame.h"
16 #include "test/gmock.h"
17 #include "test/gtest.h"
18 #include "test/scoped_key_value_config.h"
19
20 namespace webrtc {
21 namespace {
22
23 using ::testing::ElementsAre;
24 using ::testing::Eq;
25 using ::testing::IsEmpty;
26 using ::testing::Matches;
27
28 MATCHER_P(FrameWithId, id, "") {
29 return Matches(Eq(id))(arg->Id());
30 }
31
TEST(FrameBuffer3Test,RejectInvalidRefs)32 TEST(FrameBuffer3Test, RejectInvalidRefs) {
33 test::ScopedKeyValueConfig field_trials;
34 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
35 field_trials);
36 // Ref must be less than the id of this frame.
37 EXPECT_FALSE(buffer.InsertFrame(
38 test::FakeFrameBuilder().Time(0).Id(0).Refs({0}).AsLast().Build()));
39 EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));
40
41 // Duplicate ids are also invalid.
42 EXPECT_TRUE(buffer.InsertFrame(
43 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
44 EXPECT_FALSE(buffer.InsertFrame(
45 test::FakeFrameBuilder().Time(20).Id(2).Refs({1, 1}).AsLast().Build()));
46 EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1));
47 }
48
TEST(FrameBuffer3Test,LastContinuousUpdatesOnInsertedFrames)49 TEST(FrameBuffer3Test, LastContinuousUpdatesOnInsertedFrames) {
50 test::ScopedKeyValueConfig field_trials;
51 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
52 field_trials);
53 EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(absl::nullopt));
54 EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
55
56 EXPECT_TRUE(
57 buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()));
58 EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1));
59 EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
60
61 EXPECT_TRUE(buffer.InsertFrame(
62 test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()));
63 EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(2));
64 EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(2));
65 }
66
TEST(FrameBuffer3Test,LastContinuousFrameReordering)67 TEST(FrameBuffer3Test, LastContinuousFrameReordering) {
68 test::ScopedKeyValueConfig field_trials;
69 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
70 field_trials);
71
72 EXPECT_TRUE(buffer.InsertFrame(
73 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
74 EXPECT_TRUE(buffer.InsertFrame(
75 test::FakeFrameBuilder().Time(30).Id(3).Refs({2}).AsLast().Build()));
76 EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(1));
77
78 EXPECT_TRUE(buffer.InsertFrame(
79 test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
80 EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(3));
81 }
82
TEST(FrameBuffer3Test,LastContinuousTemporalUnit)83 TEST(FrameBuffer3Test, LastContinuousTemporalUnit) {
84 test::ScopedKeyValueConfig field_trials;
85 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
86 field_trials);
87
88 EXPECT_TRUE(
89 buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()));
90 EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
91 EXPECT_TRUE(buffer.InsertFrame(
92 test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()));
93 EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(2));
94 }
95
TEST(FrameBuffer3Test,LastContinuousTemporalUnitReordering)96 TEST(FrameBuffer3Test, LastContinuousTemporalUnitReordering) {
97 test::ScopedKeyValueConfig field_trials;
98 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
99 field_trials);
100
101 EXPECT_TRUE(
102 buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()));
103 EXPECT_TRUE(buffer.InsertFrame(
104 test::FakeFrameBuilder().Time(20).Id(3).Refs({1}).Build()));
105 EXPECT_TRUE(buffer.InsertFrame(
106 test::FakeFrameBuilder().Time(20).Id(4).Refs({2, 3}).AsLast().Build()));
107 EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(absl::nullopt));
108
109 EXPECT_TRUE(buffer.InsertFrame(
110 test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).AsLast().Build()));
111 EXPECT_THAT(buffer.LastContinuousTemporalUnitFrameId(), Eq(4));
112 }
113
TEST(FrameBuffer3Test,NextDecodable)114 TEST(FrameBuffer3Test, NextDecodable) {
115 test::ScopedKeyValueConfig field_trials;
116 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
117 field_trials);
118
119 EXPECT_THAT(buffer.DecodableTemporalUnitsInfo(), Eq(absl::nullopt));
120 EXPECT_TRUE(buffer.InsertFrame(
121 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
122 EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(10U));
123 }
124
TEST(FrameBuffer3Test,AdvanceNextDecodableOnExtraction)125 TEST(FrameBuffer3Test, AdvanceNextDecodableOnExtraction) {
126 test::ScopedKeyValueConfig field_trials;
127 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
128 field_trials);
129
130 EXPECT_TRUE(buffer.InsertFrame(
131 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
132 EXPECT_TRUE(buffer.InsertFrame(
133 test::FakeFrameBuilder().Time(20).Id(2).AsLast().Build()));
134 EXPECT_TRUE(buffer.InsertFrame(
135 test::FakeFrameBuilder().Time(30).Id(3).Refs({2}).AsLast().Build()));
136 EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(10U));
137
138 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
139 ElementsAre(FrameWithId(1)));
140 EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(20U));
141 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
142 ElementsAre(FrameWithId(2)));
143 EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(30U));
144 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
145 ElementsAre(FrameWithId(3)));
146 }
147
TEST(FrameBuffer3Test,AdvanceLastDecodableOnExtraction)148 TEST(FrameBuffer3Test, AdvanceLastDecodableOnExtraction) {
149 test::ScopedKeyValueConfig field_trials;
150 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
151 field_trials);
152
153 EXPECT_TRUE(buffer.InsertFrame(
154 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
155 EXPECT_TRUE(buffer.InsertFrame(
156 test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
157 EXPECT_TRUE(buffer.InsertFrame(
158 test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()));
159 EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->last_rtp_timestamp, Eq(10U));
160
161 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
162 ElementsAre(FrameWithId(1)));
163 EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->last_rtp_timestamp, Eq(30U));
164 }
165
TEST(FrameBuffer3Test,FrameUpdatesNextDecodable)166 TEST(FrameBuffer3Test, FrameUpdatesNextDecodable) {
167 test::ScopedKeyValueConfig field_trials;
168 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
169 field_trials);
170
171 EXPECT_TRUE(buffer.InsertFrame(
172 test::FakeFrameBuilder().Time(20).Id(2).AsLast().Build()));
173 EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(20U));
174
175 EXPECT_TRUE(buffer.InsertFrame(
176 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
177 EXPECT_THAT(buffer.DecodableTemporalUnitsInfo()->next_rtp_timestamp, Eq(10U));
178 }
179
TEST(FrameBuffer3Test,KeyframeClearsFullBuffer)180 TEST(FrameBuffer3Test, KeyframeClearsFullBuffer) {
181 test::ScopedKeyValueConfig field_trials;
182 FrameBuffer buffer(/*max_frame_slots=*/5, /*max_decode_history=*/10,
183 field_trials);
184 EXPECT_TRUE(buffer.InsertFrame(
185 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
186 EXPECT_TRUE(buffer.InsertFrame(
187 test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
188 EXPECT_TRUE(buffer.InsertFrame(
189 test::FakeFrameBuilder().Time(30).Id(3).Refs({2}).AsLast().Build()));
190 EXPECT_TRUE(buffer.InsertFrame(
191 test::FakeFrameBuilder().Time(40).Id(4).Refs({3}).AsLast().Build()));
192 EXPECT_TRUE(buffer.InsertFrame(
193 test::FakeFrameBuilder().Time(50).Id(5).Refs({4}).AsLast().Build()));
194 EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(5));
195
196 // Frame buffer is full
197 EXPECT_FALSE(buffer.InsertFrame(
198 test::FakeFrameBuilder().Time(60).Id(6).Refs({5}).AsLast().Build()));
199 EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(5));
200
201 EXPECT_TRUE(buffer.InsertFrame(
202 test::FakeFrameBuilder().Time(70).Id(7).AsLast().Build()));
203 EXPECT_THAT(buffer.LastContinuousFrameId(), Eq(7));
204 }
205
TEST(FrameBuffer3Test,DropNextDecodableTemporalUnit)206 TEST(FrameBuffer3Test, DropNextDecodableTemporalUnit) {
207 test::ScopedKeyValueConfig field_trials;
208 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
209 field_trials);
210 EXPECT_TRUE(buffer.InsertFrame(
211 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
212 EXPECT_TRUE(buffer.InsertFrame(
213 test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
214 EXPECT_TRUE(buffer.InsertFrame(
215 test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()));
216
217 buffer.ExtractNextDecodableTemporalUnit();
218 buffer.DropNextDecodableTemporalUnit();
219 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
220 ElementsAre(FrameWithId(3)));
221 }
222
TEST(FrameBuffer3Test,OldFramesAreIgnored)223 TEST(FrameBuffer3Test, OldFramesAreIgnored) {
224 test::ScopedKeyValueConfig field_trials;
225 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
226 field_trials);
227 EXPECT_TRUE(buffer.InsertFrame(
228 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
229 EXPECT_TRUE(buffer.InsertFrame(
230 test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
231
232 buffer.ExtractNextDecodableTemporalUnit();
233 buffer.ExtractNextDecodableTemporalUnit();
234
235 EXPECT_FALSE(buffer.InsertFrame(
236 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
237 EXPECT_FALSE(buffer.InsertFrame(
238 test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
239 EXPECT_TRUE(buffer.InsertFrame(
240 test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()));
241 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
242 ElementsAre(FrameWithId(3)));
243 }
244
TEST(FrameBuffer3Test,ReturnFullTemporalUnitKSVC)245 TEST(FrameBuffer3Test, ReturnFullTemporalUnitKSVC) {
246 test::ScopedKeyValueConfig field_trials;
247 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
248 field_trials);
249 EXPECT_TRUE(
250 buffer.InsertFrame(test::FakeFrameBuilder().Time(10).Id(1).Build()));
251 EXPECT_TRUE(buffer.InsertFrame(
252 test::FakeFrameBuilder().Time(10).Id(2).Refs({1}).Build()));
253 EXPECT_TRUE(buffer.InsertFrame(
254 test::FakeFrameBuilder().Time(10).Id(3).Refs({2}).AsLast().Build()));
255 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
256 ElementsAre(FrameWithId(1), FrameWithId(2), FrameWithId(3)));
257
258 EXPECT_TRUE(buffer.InsertFrame(
259 test::FakeFrameBuilder().Time(20).Id(4).Refs({3}).AsLast().Build()));
260 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
261 ElementsAre(FrameWithId(4)));
262 }
263
TEST(FrameBuffer3Test,InterleavedStream)264 TEST(FrameBuffer3Test, InterleavedStream) {
265 test::ScopedKeyValueConfig field_trials;
266 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
267 field_trials);
268 EXPECT_TRUE(buffer.InsertFrame(
269 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
270 EXPECT_TRUE(buffer.InsertFrame(
271 test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).AsLast().Build()));
272 EXPECT_TRUE(buffer.InsertFrame(
273 test::FakeFrameBuilder().Time(30).Id(3).Refs({1}).AsLast().Build()));
274 EXPECT_TRUE(buffer.InsertFrame(
275 test::FakeFrameBuilder().Time(40).Id(4).Refs({2}).AsLast().Build()));
276 EXPECT_TRUE(buffer.InsertFrame(
277 test::FakeFrameBuilder().Time(50).Id(5).Refs({3}).AsLast().Build()));
278
279 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
280 ElementsAre(FrameWithId(1)));
281 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
282 ElementsAre(FrameWithId(2)));
283 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
284 ElementsAre(FrameWithId(3)));
285 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
286 ElementsAre(FrameWithId(4)));
287 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
288 ElementsAre(FrameWithId(5)));
289
290 EXPECT_TRUE(buffer.InsertFrame(
291 test::FakeFrameBuilder().Time(70).Id(7).Refs({5}).AsLast().Build()));
292 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
293 ElementsAre(FrameWithId(7)));
294 EXPECT_FALSE(buffer.InsertFrame(
295 test::FakeFrameBuilder().Time(60).Id(6).Refs({4}).AsLast().Build()));
296 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty());
297 EXPECT_TRUE(buffer.InsertFrame(
298 test::FakeFrameBuilder().Time(90).Id(9).Refs({7}).AsLast().Build()));
299 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
300 ElementsAre(FrameWithId(9)));
301 }
302
TEST(FrameBuffer3Test,LegacyFrameIdJumpBehavior)303 TEST(FrameBuffer3Test, LegacyFrameIdJumpBehavior) {
304 {
305 test::ScopedKeyValueConfig field_trials(
306 "WebRTC-LegacyFrameIdJumpBehavior/Disabled/");
307 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
308 field_trials);
309
310 EXPECT_TRUE(buffer.InsertFrame(
311 test::FakeFrameBuilder().Time(20).Id(3).AsLast().Build()));
312 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
313 ElementsAre(FrameWithId(3)));
314 EXPECT_FALSE(buffer.InsertFrame(
315 test::FakeFrameBuilder().Time(30).Id(2).AsLast().Build()));
316 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty());
317 }
318
319 {
320 // WebRTC-LegacyFrameIdJumpBehavior is disabled by default.
321 test::ScopedKeyValueConfig field_trials;
322 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
323 field_trials);
324
325 EXPECT_TRUE(buffer.InsertFrame(
326 test::FakeFrameBuilder().Time(20).Id(3).AsLast().Build()));
327 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
328 ElementsAre(FrameWithId(3)));
329 EXPECT_FALSE(buffer.InsertFrame(
330 test::FakeFrameBuilder().Time(30).Id(2).Refs({1}).AsLast().Build()));
331 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(), IsEmpty());
332 EXPECT_TRUE(buffer.InsertFrame(
333 test::FakeFrameBuilder().Time(40).Id(1).AsLast().Build()));
334 EXPECT_THAT(buffer.ExtractNextDecodableTemporalUnit(),
335 ElementsAre(FrameWithId(1)));
336 }
337 }
338
TEST(FrameBuffer3Test,TotalNumberOfContinuousTemporalUnits)339 TEST(FrameBuffer3Test, TotalNumberOfContinuousTemporalUnits) {
340 test::ScopedKeyValueConfig field_trials;
341 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
342 field_trials);
343 EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(0));
344
345 EXPECT_TRUE(buffer.InsertFrame(
346 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
347 EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1));
348
349 EXPECT_TRUE(buffer.InsertFrame(
350 test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).Build()));
351 EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1));
352
353 EXPECT_TRUE(buffer.InsertFrame(
354 test::FakeFrameBuilder().Time(40).Id(4).Refs({2}).Build()));
355 EXPECT_TRUE(buffer.InsertFrame(
356 test::FakeFrameBuilder().Time(40).Id(5).Refs({3, 4}).AsLast().Build()));
357 EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(1));
358
359 // Reordered
360 EXPECT_TRUE(buffer.InsertFrame(
361 test::FakeFrameBuilder().Time(20).Id(3).Refs({2}).AsLast().Build()));
362 EXPECT_THAT(buffer.GetTotalNumberOfContinuousTemporalUnits(), Eq(3));
363 }
364
TEST(FrameBuffer3Test,TotalNumberOfDroppedFrames)365 TEST(FrameBuffer3Test, TotalNumberOfDroppedFrames) {
366 test::ScopedKeyValueConfig field_trials;
367 FrameBuffer buffer(/*max_frame_slots=*/10, /*max_decode_history=*/100,
368 field_trials);
369 EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(0));
370
371 EXPECT_TRUE(buffer.InsertFrame(
372 test::FakeFrameBuilder().Time(10).Id(1).AsLast().Build()));
373 EXPECT_TRUE(buffer.InsertFrame(
374 test::FakeFrameBuilder().Time(20).Id(2).Refs({1}).Build()));
375 EXPECT_TRUE(buffer.InsertFrame(
376 test::FakeFrameBuilder().Time(20).Id(3).Refs({2}).AsLast().Build()));
377 EXPECT_TRUE(buffer.InsertFrame(
378 test::FakeFrameBuilder().Time(40).Id(4).Refs({1}).Build()));
379 EXPECT_TRUE(buffer.InsertFrame(
380 test::FakeFrameBuilder().Time(40).Id(5).Refs({4}).AsLast().Build()));
381
382 buffer.ExtractNextDecodableTemporalUnit();
383 EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(0));
384
385 buffer.DropNextDecodableTemporalUnit();
386 EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(2));
387
388 buffer.ExtractNextDecodableTemporalUnit();
389 EXPECT_THAT(buffer.GetTotalNumberOfDroppedFrames(), Eq(2));
390 }
391
392 } // namespace
393 } // namespace webrtc
394